将信号量sem_t相关的一组API封装成Win32平台上的事件对象类之后,在Linux平台上就可以像使用事件对象那样,方便地进行线程同步了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<span style="font-size:16px;">class CEventImpl { protected: /* 创建匿名信号量 `bAutoReset true 人工重置 false 自动重置 */ CEventImpl(bool manualReset); /* 注销信号量 */ ~CEventImpl(); /* 将当前事件对象设置为有信号状态 若自动重置,则等待该事件对象的所有线程只有一个可被调度 若人工重置,则等待该事件对象的所有线程变为可被调度 */ void SetImpl(); /* 以当前事件对象,阻塞线程,将其永远挂起 直到事件对象被设置为有信号状态 */ bool WaitImpl(); /* 以当前事件对象,阻塞线程,将其挂起指定时间间隔 之后线程自动恢复可调度 */ bool WaitImpl(long milliseconds); /* 将当前事件对象设置为无信号状态 */ void ResetImpl(); private: bool m_manual; sem_t m_event; }; inline void CEventImpl::SetImpl() { int ret = sem_post(&m_event); if ( 0 != ret ) { cout<<"cannot signal event"<<endl; } } inline void CEventImpl::ResetImpl() { int sval = 0; do { sem_trywait(&m_event); sem_getvalue(&m_event, &sval); } while(sval > 0); }</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<span style="font-size:16px;">CEventImpl::CEventImpl(bool manualReset): m_manual(manualReset) { unsigned int nValue = 0; //初始化为无信号 int ret = sem_init(&m_event, 0, nValue); if ( 0 != ret ) { cout<<"sem_init failed"<<endl; } } CEventImpl::~CEventImpl() { sem_destroy(&m_event); } bool CEventImpl::WaitImpl() { int ret = sem_wait(&m_event); if ( 0 != ret ) { cout<<"CEventImpl::WaitImpl sem_wait failed"<<endl; } if ( m_manual ) { sem_post(&m_event); } return true; } bool CEventImpl::WaitImpl(long milliseconds) { if ( 0 == milliseconds ) { int ret = sem_trywait(&m_event); if ( 0 == ret ) { if ( m_manual ) { sem_post(&m_event); } } } else { int roopMax = milliseconds/10; do { usleep(10*1000); int ret = sem_trywait(&m_event); if ( 0 == ret ) { if ( m_manual ) { sem_post(&m_event); } break; } roopMax--; } while( roopMax > 0 ); } return true; }</span> |
类CEventImpl可以使用Linux平台用C++实现事件对象,同步线程或用C++实现Win32事件对象,同步线程中的测试代码对其进行测试。其结果是相同的。
发表评论
要发表评论,您必须先登录。