30

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

4

4 回答 4

38

你需要条件变量。

如果您的编译器支持std::conditionalC++11 引入的,那么您可以查看详细信息:

如果您的编译器不支持它,并且您使用的是 win32 线程,请查看以下内容:

这是一个完整例子。

如果您使用 POSIX 线程,请查看以下内容:


你可以在这里看到我conditional_variable使用 win32 原语的实现:

向下滚动,先看看它的实现,再看看并发队列实现中的用法。

条件变量的典型用法是:

//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

whereCheckCondition是检查条件的函数(或函子)。当它被虚假唤醒时,它被wait()函数内部调用,如果条件尚未满足,则函数再次休眠。在睡觉之前,原子地释放互斥锁。wait()wait()

于 2012-06-11T06:08:40.483 回答
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()
于 2012-06-11T06:14:36.973 回答
2

使用 Semaphore 发送信号。示例(应用程序清理退出)如下:

在标题中声明

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
...

在源代码中,(衍生线程);

...
sem_post(&semPrepareExit);

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

于 2016-01-12T18:33:04.170 回答
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();
于 2016-11-30T10:05:09.603 回答