DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

posted on 2023-03-15 18:00  DoubleLi  阅读(313)  评论(0编辑  收藏  举报