在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下一样,支持手动和自动。