【问题标题】:Block a thread with sleep vs block without sleep用睡眠阻塞线程与没有睡眠阻塞
【发布时间】:2015-06-28 18:09:33
【问题描述】:

我使用 C++ 和 POSIX 线程创建了一个多线程应用程序。我现在应该在其中阻塞一个线程(主线程),直到设置一个布尔标志(变为真)。

我找到了两种方法来完成这项工作。

  • 在循环中旋转没有睡眠。

    while(!flag);
    
  • 通过一个循环睡眠。

    while(!flag){
         sleep(some_int);
    }
    

如果我应该遵循第一种方式,为什么有些人会按照第二种方式编写代码?如果要使用第二种方式,为什么要让当前线程休眠?这种方式有什么缺点?

【问题讨论】:

  • 您错过了一个重要的选择:如果这些都不是正确的做法怎么办? (提示,在几乎所有情况下,这些都不是正确的做法。)
  • 使用信号量代替:声明一个全局sem_t* 并在之前使用sem_open 创建线程对其进行初始化。将设置flag = true的部分替换为sem_post,将等待while (!flag)的部分替换为sem_get
  • @barakmanos 感谢您的评论,这很清楚,但是我很想知道这两个中哪一个更适合使用。
  • 我会选择第二个选项,但这实际上取决于您的线程时间以及some_int 的值。在某些(相对罕见的)场景中,第一个选项实际上可能会在运行时间方面产生更好的结果。

标签: c++ c multithreading


【解决方案1】:

第一个选项(“忙等待”)会在等待期间浪费整个内核,从而阻止其他有用的工作完成和/或浪费能量。

第二个选项不那么浪费 - 您的等待线程使用很少的 CPU 并允许其他线程运行。但是一直切换回线程检查flag还是很浪费的。

比使用条件变量要好得多,它允许等待线程阻塞而不消耗任何资源,直到它能够继续。

【讨论】:

【解决方案2】:

while(flag); 将导致您的线程使用其分配的所有时间检查条件。这会浪费大量 CPU 周期来检查可能未更改的内容。

稍微休眠会导致线程暂停并将 CPU 让给真正需要它的程序。

你也不应该这样做;你应该使用线程库来创建一个标志对象并调用它的wait函数,这样内核就会暂停线程直到标志被设置。

【讨论】:

    【解决方案3】:

    第一种方式(只是简单的while)是浪费资源,特别是你的进程的处理器时间。

    当一个线程被放入sleep 时,操作系统可能会在讨论具有抢占式多任务处理的系统时决定处理器将用于不同的任务。从理论上讲,如果您拥有与线程一样多的处理器/内核,则不会有任何区别。

    解决方案好坏取决于所使用的操作系统,有时还取决于程序运行的架构。您应该查阅您的系统调用参考以了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 2020-03-18
      • 1970-01-01
      相关资源
      最近更新 更多