【问题标题】:waiting thread until a condition has been occurred等待线程直到条件发生
【发布时间】:2012-06-14 01:07:16
【问题描述】:

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

【问题讨论】:

标签: c++ multithreading simulator


【解决方案1】:

你需要条件变量。

如果你的编译器支持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

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

【讨论】:

    【解决方案2】:

    如果你没有 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()
    

    【讨论】:

      【解决方案3】:

      使用 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”在信号量上发出信号。主线程将在等待节点/点接收信号,然后继续。

      【讨论】:

        【解决方案4】:

        试试这样的:

        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();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-02
          • 2017-12-25
          • 1970-01-01
          • 1970-01-01
          • 2017-07-02
          • 2019-06-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多