Linux中使用条件变量实现Windows事件?
我正试图在Linux中实现非常简单的Windows事件。 仅适用于我的场景 - 3个线程,1个主要和2个辅助。 每个辅助线程通过SetEvent引发1个事件,主线程等待它。 例:
int main()
{
void* Events[2];
Events[0] = CreateEvent();
Events[1] = CreateEvent();
pthread_start(Thread, Events[0]);
pthread_start(Thread, Events[1]);
WaitForMultipleObjects(2, Events, 30000) // 30 seconds timeout
return 0;
}
int* thread(void* Event)
{
// Do something
SetEvent(Event);
// Do something
}
所以,为了实现它,我使用条件变量。 但我的问题是 - 这是一种正确的方式吗? 或者我做错了什么? 我的实施:
// Actually, this function return pointer to struct with mutex and cond
// here i just simplified example
void* CreateEvent(mutex, condition)
{
pthread_mutex_init(mutex, NULL);
pthread_cond_init(condition, NULL);
}
bool SetEvent (mutex, condition)
{
pthread_mutex_lock(mutex);
pthread_cond_signal(condition);
pthread_mutex_unlock(mutex);
}
int WaitForSingleObject(mutex, condition, timeout)
{
pthread_mutex_lock(mutex);
pthread_cond_timedwait(condition, mutex, timeout);
pthread_mutex_unlock(mutex);
}
// Call WaitForSingleObject for each event.
// Yes, i know, that its a wrong way, but it should work in my example.
int WaitForMultipleObjects(count, mutex[], condition[], timeout);
所有似乎都不错,但我认为,当我调用主线程中的SetEvent之前调用WaitFor ..函数时,会出现该问题。 在Windows中,它运行良好,但在Linux中 - 只有想法如上所述。
也许你告诉我解决问题的更好方法? 谢谢。
UPD:超时非常重要,因为其中一个辅助线程可能无法通过SetEvent()。
在stackoverflow上也有类似的问题:在Linux中WaitForSingleObject和WaitForMultipleObjects等价
另外你可以使用信号量:
sem_t semOne ;
sem_t semTwo ;
sem_t semMain ;
在主线程中:
sem_init(semOne,0,0) ;
sem_init(semTwo,0,0) ;
sem_init(semMain,0,0) ;
...
sem_wait(&semMain);
// Thread 1
sem_wait(&semOne);
sem_post(&semMain);
// Thread 2
sem_wait(&semTwo);
sem_post(&semMain);
详细描述和各种示例可以在这里找到:http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html
基于WaitForSingleObject
的描述
WaitForSingleObject函数检查指定对象的当前状态。 如果对象的状态为非信号,则调用线程将进入等待状态,直到对象发出信号或超时时间间隔过去。
该行为与代码之间的区别在于代码将始终等待条件变量,因为它不检查谓词。 这引入了pthread_condt_timewait
和pthread_cond_signal
调用之间的同步问题。
表示条件变量的一般习惯用法是:
lock mutex set predicate unlock mutex signal condition variable
当等待条件变量时:
lock mutex while ( !predicate ) { wait on condition variable } unlock mutex
基于试图完成的事情,可以将一个单独的bool
用作每个Event
的谓词。 通过引入一个谓词,如果Event
没有被发信号, WaitForSingleObject
应该只等待条件变量。 代码看起来类似于以下内容:
bool SetEvent (mutex, condition)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
signalled = true; // set predicate
pthread_mutex_unlock(mutex); // unlock mutex
pthread_cond_signal(condition); // signal condition variable
}
int WaitForSingleObject(mutex, condition, timeout)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
while (!signalled)
{
pthread_cond_timedwait(condition, mutex, timeout);
}
signalled = false; // reset predicate
pthread_mutex_unlock(mutex); // unlock mutex
}
我认为信号量在这里是一个更好的解决方案,因为它可以用于进程间。 如果未提供名称,则可以封装接口,然后使用pthread_将其初始化以供进程内使用,这可以缩短资源使用情况,但是当使用名称时,请尝试使用sem对其进行初始化,以供进程内使用。
链接地址: http://www.djcxy.com/p/64963.html上一篇: Windows Event implementation in Linux using conditional variables?
下一篇: .Net SerialPort taking over 0.5 seconds to read byte when bytes available