【问题标题】:Does msleep() give cycles to other threads?msleep() 是否给其他线程循环?
【发布时间】:2012-06-27 14:32:00
【问题描述】:

在多线程应用中,是

while (result->Status == Result::InProgress) Sleep(50);
//process results

优于

while (result->Status == Result::InProgress);
//process results

? 这样,我问第一种方法是否会在等待结果而不是不断旋转时对其他线程有礼貌?我正在等待的操作通常需要大约 1-2 秒,并且在不同的线程上。

【问题讨论】:

    标签: c++ sleep


    【解决方案1】:

    我建议在这种情况下使用信号量而不是轮询。如果您更喜欢主动等待,那么睡眠比不断评估循环条件要好得多。

    【讨论】:

      【解决方案2】:

      更好,但不是很多。

      只要result->Status不是volatile,就允许编译器减少

      while(result->Status == Result::InProgress);
      

      if(result->Status == Result::InProgress) for(;;) ;
      

      因为条件在循环内不会改变。

      调用外部(因此隐式地volatile)函数Sleep 会改变这一点,因为这可能会修改result 结构,除非编译器知道Sleep 从不修改数据。因此,根据编译器的不同,第二种实现进入无限循环的可能性要小得多。

      也不能保证对result->Status 的访问将是原子的。对于特定的内存布局和处理器架构,读取和写入此变量可能包含多个步骤,这意味着调度程序可能会决定在中间介入。

      由于此时您所交流的只是一个简单的是/否,并且接收线程也应该等待否定答复,因此最好的方法是使用您的操作系统提供的适当线程同步原语来实现此效果。这样做的好处是当条件发生变化时您的线程会立即被唤醒,并且在此期间它不使用 CPU,因为操作系统知道您的线程正在等待什么。

      在 Windows 上,使用 CreateEvent 和 co。使用事件对象进行通信;在 Unix 上,使用 pthread_cond_t 对象。

      【讨论】:

        【解决方案3】:

        是的,睡眠和变体放弃了处理器。其他线程可以接管。但是有更好的方法来等待其他线程。

        不要使用空循环。

        【讨论】:

          【解决方案4】:

          这也取决于您的操作系统调度策略。例如,Linux 默认具有 CFS 调度,因此它将处理器公平地分配给所有任务。但是,如果您将此线程设置为具有 FIFO 策略的实时线程,那么没有睡眠的代码将永远不会放弃处理器,除非有更高优先级的线程出现,否则在您退出循环之前,永远不会安排相同或更低的优先级。如果您应用 SCHED_RR,那么优先级相同或更高的进程将被调度,但不会更低。

          【讨论】:

            猜你喜欢
            • 2019-11-15
            • 2013-05-24
            • 1970-01-01
            • 1970-01-01
            • 2012-08-06
            • 2016-05-11
            • 1970-01-01
            • 2017-05-02
            • 1970-01-01
            相关资源
            最近更新 更多