linux下实现event

        在linux下实现事件,主要采用条件锁的方式实现,源码如下:

首先是event.h文件,实现event类

#include 
#include 

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



你可能感兴趣的:(linux编程)