1、第一种方法(win和linux通用)
//头文件.h
#ifndef _HIK_EVENT_H_
#define _HIK_EVENT_H_
#ifdef _MSC_VER
#include <Windows.h>
#define hik_event_handle HANDLE
#else
#include <pthread.h>
typedef struct
{
bool state;
bool manual_reset;
pthread_mutex_t mutex;
pthread_cond_t cond;
}event_t;
#define event_handle event_t*
#endif
//返回值:NULL 出错
event_handle event_create(bool manual_reset, bool init_state);
//返回值:0 等到事件,-1出错
int event_wait(event_handle hevent);
//返回值:0 等到事件,1 超时,-1出错
int event_timedwait(event_handle hevent, long milliseconds);
//返回值:0 成功,-1出错
int event_set(event_handle hevent);
//返回值:0 成功,-1出错
int event_reset(event_handle hevent);
//返回值:无
void event_destroy(event_handle hevent);
#endif
///
//源文件.cpp:
#include "event.h"
#ifdef __linux
#include <sys/time.h>
#include <errno.h>
#endif
#include <iostream>
event_handle event_create(bool manual_reset, bool init_state)
{
#ifdef _MSC_VER
HANDLE hevent = CreateEvent(NULL, manual_reset, init_state, NULL);
#else
event_handle hevent = new(std::nothrow) event_t;
if (hevent == NULL)
{
return NULL;
}
hevent->state = init_state;
hevent->manual_reset = manual_reset;
if (pthread_mutex_init(&hevent->mutex, NULL))
{
delete hevent;
return NULL;
}
if (pthread_cond_init(&hevent->cond, NULL))
{
pthread_mutex_destroy(&hevent->mutex);
delete hevent;
return NULL;
}
#endif
return hevent;
}
int event_wait(event_handle hevent)
{
#ifdef _MSC_VER
DWORD ret = WaitForSingleObject(hevent, INFINITE);
if (ret == WAIT_OBJECT_0)
{
return 0;
}
return -1;
#else
if (pthread_mutex_lock(&hevent->mutex))
{
return -1;
}
while (!hevent->state)
{
if (pthread_cond_wait(&hevent->cond, &hevent->mutex))
{
pthread_mutex_unlock(&hevent->mutex);
return -1;
}
}
if (!hevent->manual_reset)
{
hevent->state = false;
}
if (pthread_mutex_unlock(&hevent->mutex))
{
return -1;
}
return 0;
#endif
}
int event_timedwait(event_handle hevent, long milliseconds)
{
#ifdef _MSC_VER
DWORD ret = WaitForSingleObject(hevent, milliseconds);
if (ret == WAIT_OBJECT_0)
{
return 0;
}
if (ret == WAIT_TIMEOUT)
{
return 1;
}
return -1;
#else
int rc = 0;
struct timespec abstime;
struct timeval tv;
gettimeofday(&tv, NULL);
abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
if (abstime.tv_nsec >= 1000000000)
{
abstime.tv_nsec -= 1000000000;
abstime.tv_sec++;
}
if (pthread_mutex_lock(&hevent->mutex) != 0)
{
return -1;
}
while (!hevent->state)
{
if (rc = pthread_cond_timedwait(&hevent->cond, &hevent->mutex, &abstime))
{
if (rc == ETIMEDOUT) break;
pthread_mutex_unlock(&hevent->mutex);
return -1;
}
}
if (rc == 0 && !hevent->manual_reset)
{
hevent->state = false;
}
if (pthread_mutex_unlock(&hevent->mutex) != 0)
{
return -1;
}
if (rc == ETIMEDOUT)
{
//timeout return 1
return 1;
}
//wait event success return 0
return 0;
#endif
}
int event_set(event_handle hevent)
{
#ifdef _MSC_VER
return !SetEvent(hevent);
#else
if (pthread_mutex_lock(&hevent->mutex) != 0)
{
return -1;
}
hevent->state = true;
if (hevent->manual_reset)
{
if(pthread_cond_broadcast(&hevent->cond))
{
return -1;
}
}
else
{
if(pthread_cond_signal(&hevent->cond))
{
return -1;
}
}
if (pthread_mutex_unlock(&hevent->mutex) != 0)
{
return -1;
}
return 0;
#endif
}
int event_reset(event_handle hevent)
{
#ifdef _MSC_VER
//ResetEvent 返回非零表示成功
if (ResetEvent(hevent))
{
return 0;
}
return -1;
#else
if (pthread_mutex_lock(&hevent->mutex) != 0)
{
return -1;
}
hevent->state = false;
if (pthread_mutex_unlock(&hevent->mutex) != 0)
{
return -1;
}
return 0;
#endif
}
void event_destroy(event_handle hevent)
{
#ifdef _MSC_VER
CloseHandle(hevent);
#else
pthread_cond_destroy(&hevent->cond);
pthread_mutex_destroy(&hevent->mutex);
delete hevent;
#endif
}
2、第二种方法(linux下实现win的event)
(1)头文件
首先是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);
}
(2)接下来是调用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下一样,支持手动和自动。