Event.h
#pragma once
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <string>
#include <memory>
#include <stdio.h>
#include <iostream>
#include <pthread.h>
#ifndef _WIN32
#include <unistd.h>
#include <semaphore.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/shm.h>
#else
#include <Windows.h>
#endif
using namespace std;
class Event
{
public:
void Wait()
{
std::unique_lock<std::mutex> lker(m_mtx);
m_cv.wait(lker);
}
bool Wait(int nMillSec)
{
std::chrono::milliseconds mills(nMillSec);
std::unique_lock<std::mutex> lker(m_mtx);
auto ret = m_cv.wait_for(lker, mills);
return (ret != std::cv_status::timeout);
}
void NotifyOne()
{
m_cv.notify_one();
}
void NotifyAll()
{
m_cv.notify_all();
}
private:
std::mutex m_mtx;
std::condition_variable m_cv;
};
class Semaphore
{
public:
Semaphore(int nCount = 0) :m_count(nCount) {}
void Wait()
{
std::unique_lock<std::mutex> lker(m_mtx);
m_cv.wait(lker, [this]() {return m_count > 0; });
--m_count;
}
void Signal()
{
{
std::unique_lock<std::mutex> lker(m_mtx);
++m_count;
}
m_cv.notify_one();
}
private:
int m_count;
std::mutex m_mtx;
std::condition_variable m_cv;
};
class name_mutex
{
public:
name_mutex(string name, int id)
{
#ifndef _WIN32
m_cMutexName = name;
key_t shmKey = ftok(m_cMutexName.c_str(), id);
size_t MAPPING_SIZE = 512;
if((m_mfd = shmget(shmKey, MAPPING_SIZE, IPC_CREAT|IPC_EXCL|0666)) == -1)
{
m_mfd = shmget(shmKey, MAPPING_SIZE, 0) ;
}
if(m_mfd == -1)
m_pMutex = NULL;
else
{
m_pMutex = (pthread_mutex_t*)shmat(m_mfd , NULL , 0);
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(m_pMutex, &mutex_attr);
}
#else
m_cMutexName = name+to_string(id);
m_pMutex = CreateMutex(NULL, FALSE, m_cMutexName.c_str());
#endif
if (m_pMutex == NULL)
{
}
else
{
}
}
~name_mutex()
{
#ifndef _WIN32
if(m_pMutex == NULL)
return ;
pthread_mutex_destroy(m_pMutex);
shmdt(m_pMutex);
shmid_ds ds_buf;
shmctl(m_mfd, IPC_STAT, &ds_buf);
if(ds_buf.shm_nattch == 0)
{
shmctl(m_mfd, IPC_RMID , NULL);
}
m_pMutex = NULL ;
#else
CloseHandle(m_pMutex);
#endif
}
void lock()
{
#ifndef _WIN32
pthread_mutex_lock(m_pMutex);
#else
WaitForSingleObject(m_pMutex, INFINITE);
#endif
}
void unlock()
{
#ifndef _WIN32
pthread_mutex_unlock(m_pMutex);
#else
ReleaseMutex(m_pMutex);
#endif
}
int trylock(unsigned int times)
{
int ret = -1;
#ifndef _WIN32
for(int i=0; i<times; i++)
{
ret = pthread_mutex_trylock(m_pMutex);
if(ret == 0) break;
usleep(500);
}
#else
ret = WaitForSingleObject(m_pMutex, times);
#endif
return ret;
}
#ifndef _WIN32
pthread_mutex_t *m_pMutex;
int m_mfd;
#else
void* m_pMutex;
#endif
private:
string m_cMutexName;
};
class name_lock
{
public:
name_lock(shared_ptr<name_mutex> mtx)
{
m_mtx = mtx;
m_mtx->lock();
}
~name_lock()
{
m_mtx->unlock();
}
private:
shared_ptr<name_mutex> m_mtx;
};
main.cpp
#include "Event.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
shared_ptr<name_mutex> m_mtxDevice;
m_mtxDevice.reset(new name_mutex("MUTEX",1));
while(true)
{
{
name_lock lg(m_mtxDevice);
do something....
}
}
}
编译:
g++ -std=gnu++11 main.cpp -lpthread
|