等待线程直到条件发生

时间:2012-06-11 05:26:30

标签: c++ multithreading simulator

我想等待在Simultaneous模拟器中执行的2个线程的一个线程,直到条件发生,可能是在模拟器中运行程序1000个或更多周期后发生的情况,条件发生后等待线程再次执行,我该怎么办?

4 个答案:

答案 0 :(得分:32)

您需要条件变量。

如果你的编译器支持C ++ 11引入的std::conditional,那么你可以看到这个细节:

如果你的编译器不支持它,并且使用win32线程,那么请看:

here就是一个完整的例子。

如果您使用POSIX线程,请参阅:


您可以在此处使用win32原语查看我的conditional_variable实现:

向下滚动并首先查看它的实现,然后查看并发队列实现中的用法。

条件变量的典型用法是:

//lock the mutex first!
scoped_lock myLock(myMutex); 

//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);

//Execute this code only if the condition is met

其中CheckCondition是检查条件的函数(或函子)。它在虚假唤醒时由内部wait()函数调用,如果条件尚未满足,则wait()函数再次休眠。在进入睡眠状态之前,wait()会释放互斥锁,原子地

答案 1 :(得分:6)

如果您没有C ++ 11,但确实有一个支持POSIX线程的系统,那么您可以使用条件变量。还有其他选择,但根据您描述问题的方式,条件变量可能是最直接的。

pthread条件变量与互斥锁一起使用。条件变量的技巧是等待它会导致获取的互斥锁被释放,直到等待调用返回,此时再次获取互斥锁。顺序是:

  • 获取互斥
  • 虽然PREDICATE不是真的
    • 等待条件变量
  • 在关键部分工作
  • 如果PREDICATE为真
    • 信号条件变量
  • 发布互斥

如果多个线程正在进入上面的相同关键部分,则使用信号步骤。

如果另一个线程可以访问同一个互斥锁来修改影响PREDICATE的状态,那么该线程应检查是否需要发信号通知。

  • 获取互斥
  • 在关键部分工作
  • 如果PREDICATE为真
    • 信号条件变量
  • 发布互斥

感兴趣的POSIX命令是:

pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_wait()
pthread_cond_signal()

答案 2 :(得分:1)

使用信号量进行信令传输。示例(应用程序清除退出)如下:

在标题

中声明
static sem_t semPrepareExit;            //declaration

在源(主线程)中;

sem_init(&semPrepareExit, 0, 0);        ///semaphore initialized
...
///now wait for the signal on the semaphore, to proceed hereforth
sem_post(&semPrepareExit);
/// cleanup ahead
...

在source中,(spawned-thread);

...
sem_post(&semPrepareExit);

现在,只要您使用" sem_post"在信号量上发出信号即可。主线程将在等待节点/点接收信号,然后继续进行。

答案 3 :(得分:1)

尝试这样的事情:

class CmyClass
{
   boost::mutex mtxEventWait;
   bool WaitForEvent(long milliseconds);
   boost::condition cndSignalEvent;
};

bool CmyClass::WaitForEvent(long milliseconds)
{
   boost::mutex::scoped_lock mtxWaitLock(mtxEventWait);
   boost::posix_time::time_duration wait_duration = boost::posix_time::milliseconds(milliseconds); 
   boost::system_time const timeout=boost::get_system_time()+wait_duration; 
   return cndSignalEvent.timed_wait(mtxEventWait,timeout); // wait until signal Event 
}

//所以为了等待然后调用WaitForEvent方法

WaitForEvent(1000); // it will timeout after 1 second

//这是一个事件如何发出信号:

cndSignalEvent.notify_one();