在Linux的Windows事件执行使用条件变量?(Windows Event implementa

2019-07-02 09:11发布

我想实现在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);

和所有似乎不错,但我认为,当我打电话WaitFor的..在辅助线程SetEvent的前主线程函数将被调用就会出现这个问题。 在Windows中,它的工作很好,但在Linux中 - 是上述唯一的想法。

也许你告诉我更好的办法来解决呢? 谢谢。

UPD:超时是非常重要的,因为二次线程之一可能无法通过SetEvent的()。

Answer 1:

有计算器上类似的问题已经: WaitForSingleObject的和WaitForMultipleObjects的相当于在Linux

此外,还可以使用信号量:

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

以前的链接不再可用。 在互联网档案馆的Wayback机器最新的存档版本是: https://web.archive.org/web/20130515223326/http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html



Answer 2:

上的描述立足本WaitForSingleObject

WaitForSingleObject函数检查指定对象的当前状态。 如果对象的状态是无信号,直到对象处于信号或超时间隔时调用线程进入等待状态。

这种行为和代码之间的区别是,该代码会一直等待条件变量,因为它不检查一个谓语。 这将引入之间的同步问题pthread_condt_timewaitpthread_cond_signal调用。

用于信令条件变量的一般成语是:

lock mutex
set predicate
unlock mutex
signal condition variable

并等待条件变量时:

lock mutex
while ( !predicate )
{ 
  wait on condition variable
}
unlock mutex

基于什么努力来完成,一个独立的bool可作为每个断言Event 。 通过引入谓词, WaitForSingleObject只应在条件变量,如果等待Event尚未发出信号。 该代码将类似于以下内容:

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
}


Answer 3:

我认为信号是一种更好的解决方案在这里,因为它可以用于进程间。 你可以用接口,如果名称不提供,那么使用的pthread_初始化它的进程内使用,可短资源使用,但是当使用的名称,尽量使用SEM初始化,对于进程内使用。



文章来源: Windows Event implementation in Linux using conditional variables?