Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Linux中使用条件变量实现Windows事件?_C++_Linux_Multithreading_Synchronization_Mutex - Fatal编程技术网

C++ 在Linux中使用条件变量实现Windows事件?

C++ 在Linux中使用条件变量实现Windows事件?,c++,linux,multithreading,synchronization,mutex,C++,Linux,Multithreading,Synchronization,Mutex,我试图在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, Ev

我试图在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()。

在stackoverflow上已经存在类似的问题:

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

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);
详细说明和各种示例可在此处找到:------

上一个链接不再可用。Internet Archive Wayback机器上的最新存档版本为:

基于对

WaitForSingleObject函数检查指定对象的当前状态。如果对象的状态为非信号状态,则调用线程将进入等待状态,直到对象收到信号或超时间隔结束

该行为与代码之间的区别在于,代码将始终等待条件变量,因为它不会检查谓词。这将在
pthread\u condt\u timewait
pthread\u cond\u信号
调用之间引入同步问题

发送条件变量信号的一般习惯用法是:

lock mutex set predicate unlock mutex signal condition variable
我认为信号量是一个更好的解决方案,因为它可以在进程间使用。
如果未提供名称,则可以包装接口,然后使用pthread_u初始化接口以供进程内使用,这样可以缩短资源使用时间,但使用名称时,请尝试使用sem初始化接口以供进程内使用。

谢谢,但超时怎么办?正如我所知,信号量没有它。你可以简单地使用sem_timedwait()而不是sem_wait()。我认为,信号量不能timedwait。。。谢谢)为什么他们不能等?sem_timewait()存在一些错误。你可以找到一些线索或线索。我们有一个名为
pevents
的开源(麻省理工学院许可)库,它在linux上实现WIN32手动和自动重置事件,包括WaitForSingleObject和WaitForMultipleObjects克隆:可能是 lock mutex while ( !predicate ) { wait on condition variable } unlock mutex
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
}