【问题标题】:How to force the order of execution of two processes?如何强制两个进程的执行顺序?
【发布时间】:2012-08-07 06:21:05
【问题描述】:

我有一个父进程,它产生一定数量的子进程。这些子进程做一些工作并通过进程间消息队列向父进程发送带有结果的消息。但是,我也希望子进程等待父进程向它们发送消息已被正确接收和处理的确认,并且只有在收到父进程的此类信号后才终止。

现在,代码看起来或多或少是这样的:

parent                      child
spawn process
wait for message            do processing
                            send message
receive message             wait on condvar
save the message
notify the condvar          resume execution
wait for child termination  terminate

如果父母在孩子甚至开始等待它之前在 condvar 上执行notify,这当然会导致死锁 - 如果发生这种情况,那么父母会等待孩子退出,而孩子等待条件变量上的信号。

所以,我的问题是:如何确保孩子总是首先执行wait,即在父母执行notify之前?还是我对整个问题的看法完全错了?

提前谢谢你。

【问题讨论】:

  • 使用一些记得被通知的进程间对象?您正在开发什么操作系统?
  • 视窗。不过,如果 Boost 提供这样的功能,我宁愿使用它。
  • 那么,C++ 呢?可能值得为此和/或 Boost 添加标签。
  • 其实哪种语言都没有关系(除了说用哪种语言编写代码示例)。问题在于如何使用 condvar,并且任何具有“condvar”的语言都以相同的方式使用它。
  • 是的 + 对于@Damien_The_Unbeliever - 我只是为此使用命名事件或信号量。 Boost 似乎有点缺乏基本的同步原语 :(

标签: c++ multithreading boost deadlock


【解决方案1】:

是的,您以错误的方式处理问题。或者更确切地说,以它们不应该工作的方式使用 condvars。 Condvar 是一种通知另一个线程“某事”,一个条件,已经改变的方法。正是这种条件允许线程终止。

您需要三个元素来使用 condvar:conditionmutexcondvar 本身。比通知线程会做:

{
    unique_lock(mutex);
    condition = true;
    condvar.notify();
}

等待线程会做:

{
    unique_lock(mutex);
    while(!condition)
        condvar.wait(mutex);
}

(使用 RAII 来锁定互斥体,所以我不认为直接调用 .lock().unlock() 方法是个好主意)

请注意,while 很重要wait 可能会在未通知的情况下虚假唤醒!

【讨论】:

    【解决方案2】:

    使用一个名为信号量或事件的进程间 - 保持状态的东西,这样即使在孩子等待之前父母发出信号,仍然会收到信号。

    【讨论】:

    • 我最终使用了一个名为 semaphore 的进程间,因为我相信这在这种情况下更合适,一个持有状态的对象。谢谢!
    • 请不要提及事件。它们是 Windows 特定的条件变量的缩减版本,在其他任何地方都不存在(另一方面,Windows 难以实现完整的 condvar)。另一方面,信号量无处不在,可以很好地用于“完成”。
    • 事件以一种或另一种形式存在于多个嵌入式多任务器上。 TBH,我也很少使用它们,尽管它们偶尔有用,例如。当一个线程需要暂时暂停时。也许 Windows 难以实现 condvars 是因为它不想支持虚假唤醒?
    猜你喜欢
    • 2010-12-23
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    相关资源
    最近更新 更多