在linux下实现事件,主要采用条件锁的方式实现,源码如下:
首先是event.h文件,实现event类
#include <pthread.h>
#include <sys/time.h>
const int INFINITE = -1;
class CEvent
{
public:
CEvent(bool bIsManualReset, bool bInitialSignaled);
~CEvent();
bool CreateEvent();
bool Set();
bool Reset();
bool Wait(int cms);
private:
bool EnsureInitialized();
bool m_bIsManualReset;
bool m_bEventStatus;
bool m_bMutexInitialized;
pthread_mutex_t m_mutex;
bool m_bCondInitialized;
pthread_cond_t m_cond;
};
CEvent::CEvent(bool bIsManualReset, bool bInitialSignaled)
: m_bIsManualReset(bIsManualReset)
, m_bEventStatus(bInitialSignaled)
, m_bMutexInitialized(false)
, m_bCondInitialized(false)
{
}
CEvent::~CEvent()
{
if (m_bMutexInitialized)
{
pthread_mutex_destroy(&m_mutex);
m_bMutexInitialized = false;
}
if (m_bCondInitialized)
{
pthread_cond_destroy(&m_cond);
m_bCondInitialized = false;
}
}
bool CEvent::CreateEvent()
{
if (!m_bMutexInitialized)
{
if (0 == pthread_mutex_init(&m_mutex, NULL))
{
m_bMutexInitialized = true;
}
}
if (!m_bCondInitialized)
{
if (0 == pthread_cond_init(&m_cond, NULL))
{
m_bCondInitialized = true;
}
}
return ( m_bMutexInitialized && m_bCondInitialized);
}
bool CEvent::EnsureInitialized()
{
return ( m_bMutexInitialized && m_bCondInitialized);
}
bool CEvent::Set()
{
if (!EnsureInitialized())
{
return false;
}
pthread_mutex_lock(&m_mutex);
m_bEventStatus = true;
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
return true;
}
bool CEvent::Reset()
{
if (!EnsureInitialized())
{
return false;
}
pthread_mutex_lock(&m_mutex);
m_bEventStatus = false;
pthread_mutex_unlock(&m_mutex);
return true;
}
bool CEvent::Wait(int cms)
{
if (!EnsureInitialized())
{
return false;
}
pthread_mutex_lock(&m_mutex);
int error = 0;
if (cms != INFINITE)
{
struct timeval tv;
gettimeofday(&tv, NULL);
struct timespec ts;
ts.tv_sec = tv.tv_sec + (cms / 1000);
ts.tv_nsec = tv.tv_usec * 1000 + (cms % 1000) * 1000000;
if (ts.tv_nsec >= 1000000000)
{
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
while ((!m_bEventStatus) && (error == 0))
{
error = pthread_cond_timedwait(&m_cond, &m_mutex, &ts);
}
}
else
{
while ((!m_bEventStatus) && (error == 0))
{
error = pthread_cond_wait(&m_cond, &m_mutex);
}
}
if (0 == error && !m_bIsManualReset)
{
m_bEventStatus = false;
}
pthread_mutex_unlock(&m_mutex);
return (0 == error);
}
接下来是调用event类的文件main.cpp:
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include "event.h"
CEvent *g_event = NULL;
CEvent *CreateEvent(bool bManualReset, bool bInitialState)
{
CEvent *pEvent = new CEvent(bManualReset, bInitialState);
assert(pEvent);
bool bRet = pEvent->CreateEvent();
assert(bRet);
return pEvent;
}
unsigned int WaitForSingleObject(CEvent *pEvent, int cms)
{
assert(pEvent);
if( pEvent->Wait(cms) )
{
return 0;
}
return 1;
}
bool CloseHandle(CEvent *pEvent)
{
delete pEvent;
}
bool SetEvent(CEvent *pEvent)
{
pEvent->Set();
}
bool ResetEvent(CEvent *pEvent)
{
pEvent->Reset();
}
void *pFunc1(void *pEvent)
{
while (1)
{
WaitForSingleObject(g_event, INFINITE);
printf("this is func1 print!\n");
sleep(1);
ResetEvent(g_event);
}
}
void *pFunc2(void *pEvent)
{
while (1)
{
sleep(5);
printf("this is func2 print!\n");
SetEvent(g_event);
}
}
int main()
{
//g_event = CreateEvent(false, true);
g_event = CreateEvent(true, true);
pthread_t pid1;
pthread_t pid2;
pthread_create(&pid1, NULL, pFunc1, NULL);
pthread_create(&pid2, NULL, pFunc2, NULL);
pthread_join(pid1, NULL);
pthread_join(pid2, NULL);
CloseHandle(g_event);
return 0;
}
在main.cpp文件中对事件类进行的使用函数进行封装,然后在两个线程中可以采用类似于windows中使用事件的形式来使用。上面的event事件同windows下一样,支持手动和自动。