在Linux下AutoResetEvent的C ++等价物是什么?

AutoResetEvent在MSDN中的说明

我正在尝试将在C#中实现的线程池移植到Linux下的C ++中。 我不知道我应该使用哪些function与“AutoResetEvent”类似的行为。

AutoResetEvent最类似于二进制信号量。 说“条件变量”的人本身并没有错,但条件变量在相似的情况下使用,而不是类似的对象。 您可以在条件变量之上实现(未命名的)AutoResetEvent:

#include <pthread.h> #include <stdio.h> class AutoResetEvent { public: explicit AutoResetEvent(bool initial = false); ~AutoResetEvent(); void Set(); void Reset(); bool WaitOne(); private: AutoResetEvent(const AutoResetEvent&); AutoResetEvent& operator=(const AutoResetEvent&); // non-copyable bool flag_; pthread_mutex_t protect_; pthread_cond_t signal_; }; AutoResetEvent::AutoResetEvent(bool initial) : flag_(initial) { pthread_mutex_init(&protect_, NULL); pthread_cond_init(&signal_, NULL); } void AutoResetEvent::Set() { pthread_mutex_lock(&protect_); flag_ = true; pthread_mutex_unlock(&protect_); pthread_cond_signal(&signal_); } void AutoResetEvent::Reset() { pthread_mutex_lock(&protect_); flag_ = false; pthread_mutex_unlock(&protect_); } bool AutoResetEvent::WaitOne() { pthread_mutex_lock(&protect_); while( !flag_ ) // prevent spurious wakeups from doing harm pthread_cond_wait(&signal_, &protect_); flag_ = false; // waiting resets the flag pthread_mutex_unlock(&protect_); return true; } AutoResetEvent::~AutoResetEvent() { pthread_mutex_destroy(&protect_); pthread_cond_destroy(&signal_); } AutoResetEvent event; void *otherthread(void *) { event.WaitOne(); printf("Hello from other thread!\n"); return NULL; } int main() { pthread_t h; pthread_create(&h, NULL, &otherthread, NULL); printf("Hello from the first thread\n"); event.Set(); pthread_join(h, NULL); return 0; } 

但是,如果您需要命名自动重置事件,则可能需要查看信号量,并且可能在翻译代码时稍微困难一些。 无论哪种方式,我会仔细看你的平台上的pthreads的文档,条件变量和自动重置事件是不一样的,并不相同。

我很确定你正在寻找条件变量。 接受的答案这另一个SO问题: 在C#中的条件变量 – 似乎证实了这一点。

有关POSIX线程中条件变量的详细信息,请参阅本教程 。

您可以使用POSIX互斥和条件变量轻松地重新实现Win32 API事件对象。

不过上面的一些评论让我说明这一点:

一个条件变量不是类似于一个Event对象。 条件变量与事件的根本不同之处在于它没有内存或状态,因为如果在调用pthread_cond_signalpthread_cond_broadcast的时候,没有任何人在条件变量处被阻塞,则特别是如果线程稍后通过pthread_cond_wait阻塞它阻塞。

我试图画一个快速的自动重置事件实现:

 class event { public: event(): signalled_ (false) {} void signal () { std::unique_lock<std::mutex> lock(mutex_); signalled_ = true; cond_.notify_one (); } void wait () { std::unique_lock<std::mutex> lock(mutex_); while (!signalled_) cond_.wait (lock); signalled_ = false; } protected: std::mutex mutex_; std::condition_variable cond_; bool signalled_; }; 

条件变量等于AutoResetEvent。 他们相当于显示器。 差异是非常重要的,如果使用不当,可能会导致死锁:

想象一下C#程序中的两个线程A和B. A调用WaitOne()和B调用Set()。 如果B在A到达对WaitOne()的调用之前执行Set(),则没有问题,因为由Set()发送给AutoResetEvent()的信号是持久的,并且在执行WaitOne()之前将保持置位状态。

现在在C中,想象两个线程C和D.C调用wait(),D调用notify()。 如果C正在等待D调用notify(),则一切正常。 如果在D调用notify()之前C没有设法达到wait(),那么就会发生死锁,因为如果没有人等待,信号就会丢失,条件变量的状态仍然是“未设置”。

对此非常小心。

Boost的Thread / Condition文档中的例子与正常的ManualResetEvent和AutoResetEvent用法非常相似: http : //www.boost.org/doc/libs/1_53_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
(为了清晰起见,我做了一些小的修改)

 boost::condition_variable cond; boost::mutex mut; bool data_ready; void wait_for_data_to_process() { boost::unique_lock<boost::mutex> lock(mut); while(!data_ready) { cond.wait(lock); } } void prepare_data_for_processing() { { //scope for lock_guard boost::lock_guard<boost::mutex> lock(mut); data_ready=true; } cond.notify_one(); } 

请注意,条件提供了AutoResetEvent和ManualResetEvent的等待/通知机制,但需要互斥体才能工作。

那么,最有可能的就是互斥体 – 你有一些调用者需要一个共享资源,但是只允许一个。在互斥体的情况下,调用者会尝试获取互斥体(例如phtread_mutex_lock),做他们的事情,然后释放(pthread_mutex_unlock),以便其他一些调用者可以进入。