条件等待开销

时间:2010-10-18 15:24:45

标签: c++ linux multithreading boost pthreads

使用boost::conditional_variableACE_Conditional或直接pthread_cond_wait时,是否有等待的开销?这些是更具体的问题:

  1. 在等待线程未计划之后,是否会在等待到期之前将其安排回来,然后再次进行计划,否则它将保持未计划直到发出信号?
  2. wait是否定期获取互斥锁?在这种情况下,我猜想每次迭代浪费系统调用的一些CPU时间来锁定和释放互斥锁。它与不断获取和发布互斥锁是一样的吗?
  3. 那么,信号和从wait返回的时间间隔过了多长时间?
  4. Afaik,当使用信号量时,获取调用响应性取决于调度程序时间片大小。它在pthread_cond_wait中如何运作?我认为这是依赖于平台的。我对Linux更感兴趣,但如果有人知道它在其他平台上是如何工作的,它也会有所帮助。

    还有一个问题:是否为每个条件分配了额外的系统资源?我不会在我的代码中创建30000个互斥锁,但是我应该担心30000个使用相同的互斥锁的条件吗?

2 个答案:

答案 0 :(得分:6)

以下是pthread_cond手册页中的内容:

  

pthread_cond_wait以原子方式解锁互斥锁,并等待条件变量cond发出信号。线程执行暂停,不消耗任何CPU时间,直到发出条件变量信号。

所以从这里开始我会回答以下问题:

  1. 在等待发出信号或取消等待之前,不会安排等待线程。
  2. 没有定期互斥收购。在等待返回之前,只会重新获取一次互斥锁。
  3. 由于互斥锁释放,信号和等待返回之间传递的时间与线程调度的时间类似。
  4. 关于资源,在同一手册页上:

      

    在LinuxThreads实现中,没有资源与条件变量相关联,因此除了检查条件没有等待线程外,pthread_cond_destroy实际上什么都不做。

    更新:我挖掘了pthread_cond_ *函数的来源,行为如下:

    1. Linux中的所有pthread条件都是使用futex实现的。
    2. 当一个线程调用wait时,它被暂停和未调度。线程id插入等待线程列表的尾部。
    3. 当一个线程调用signal时,列表头部的线程被安排回来。 因此,唤醒与调度程序一样高效,不消耗操作系统资源,唯一的内存开销是等待列表的大小(参见futex_wake函数)。

答案 1 :(得分:1)

如果变量已处于“错误”状态,则只应调用pthread_cond_wait。由于它总是等待,因此总是存在与将当前线程置于休眠和切换相关的开销。

当线程未预定时,它是未预定的。它不应该使用任何资源,但当然理论上可以严格执行操作系统。允许在信号之前重新获取互斥锁,甚至返回信号(这就是为什么你必须仔细检查条件),但操作系统将被实现,所以这不会影响性能,如果它发生在所有。它不会自发地发生,而是响应另一个可能不相关的信号。

30000互斥量不应该是一个问题,但有些操作系统可能会遇到30000个睡眠线程的问题。