【问题标题】:How can I check for the completion of threads without blocking?如何在不阻塞的情况下检查线程的完成?
【发布时间】:2011-03-19 12:16:38
【问题描述】:

我生成了随机数量的线程,并且我的主线程需要在紧密循环中充当计时器。我想检查子线程是否结束,如果是,我想打破紧密循环。但是,我无法找到任何方法来做到这一点而不会阻塞。

我最好的想法是使用一个等于将要创建的随机线程数的变量。当一个线程即将完成时,它应该减少变量。同时主线程可以快速检查变量是否大于0,如果是则继续循环。

希望有更好的方法。

【问题讨论】:

标签: c pthreads


【解决方案1】:

您的主线程在等待时是否需要做其他事情?为了完全回答您的问题,我需要更好地解释您想要实现的目标,但这里有一些工具可以解决您的问题:

  • 在每次循环迭代时检查一个普通变量。您需要围绕检查执行一些锁定原语,以确保内存屏障可移植,否则您可能会读取过时的值。
  • 信号。丑陋,但你可以让工作线程使用pthread_kill 向主线程发送一个信号,这可能会中断它正在做的任何事情。您将不得不处理有关哪些操作是异步信号安全的问题(pthread 函数都不是)。
  • 条件变量。您可以使用pthread_cond_wait(或pthread_cond_timedwait,如果您想在没有线程退出的情况下在给定时间间隔后采取一些行动)。
  • 信号量。您可以将信号量用作原子计数器,或将其用作条件变量。

【讨论】:

  • 主线程充当全局时钟,它每 50 微秒迭代一次并更新线程读取的时钟变量。到目前为止,我认为普通变量是迄今为止最好的主意,但它会在循环中引入一点延迟,但 50 微秒的确切时间并不是太重要。我正在将线程与时钟同步,这就是为什么阻塞是不可接受的。
  • @Google:如果你想在定时器上同步线程,你见过pubs.opengroup.org/onlinepubs/009695399/functions/…吗?仅当您知道涉及多少线程时才适用,但是,如果线程随心所欲地消失,则无法使用。
  • 如果您的线程一次可以休眠 50 微秒,我会使用 pthread_cond_timedwait(这需要绝对时间,而不是相对时间,因此不会累积错误)等待工作线程退出时发出信号的条件变量。
【解决方案2】:

您可以使用pthread_tryjoin_nppthread_timedjoin_np,它们不会阻塞或有超时。

阅读手册页以了解确切的语义。这些是特定于 Linux 的,正如它们的名称和手册页所述,它们是不可移植的。所以YMMV。

【讨论】:

  • 这些是丑陋的不可移植(因此是_np)接口,与便携替代品相比,优势为零。
  • 公平地说,我以某种方式想象这个问题与 Linux 有关。改写了我的答案以强调不可移植性。
  • 谢谢,我阅读了手册页——如果没有一个普通变量来比较已加入的线程数,我不知道如何跟踪我需要加入的线程数。
  • @Google:如果我使用它,我会在主线程中创建一个 pthread_t 数组。然后每次围绕它的循环,主线程在第一个线程上执行tryjoin,该线程之前没有返回非 EBUSY 值。如果返回 EBUSY,请再次执行主循环。否则,将指针增加到“以前未完成的第一个线程”和tryjoin。总成本限制为每次围绕主循环一个tryjoin,加上每个创建线程一个tryjoin
  • 您不仅需要跟踪有多少线程,还需要准确跟踪哪些个线程需要等待。我会使用某种列表/队列结构来保存它,并处理不再需要的元素。或者一个简单的数组可能取决于上下文/要求(在你的问题中根本不是很清楚)
猜你喜欢
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多