【问题标题】:Why one can't do multiple pthread_joins on the same thread?为什么不能在同一个线程上执行多个 pthread_joins?
【发布时间】:2015-12-16 01:50:17
【问题描述】:

来自https://computing.llnl.gov/tutorials/pthreads/

一个加入线程可以匹配一个 pthread_join() 调用。在同一个线程上尝试多个连接是一个逻辑错误。

也来自“man pthread_join”:

如果多个线程同时尝试加入同一个线程,结果是不确定的。

但是,从程序员的角度来看,多个线程可能希望等待单个线程完成(类似于屏障)是完全合理的。

例如,我们可能有 thread1、thread2 独立运行,我们可能希望两个线程都等到 thread3 完成。

这个限制背后有什么技术原因吗?

【问题讨论】:

  • 一旦pthread_join() 返回,与退出线程关联的最后一个资源将被释放。没有其他pthread_join() 可以触及该线程,因为它什么都没有留下。必须这样,否则 pthread-library 怎么知道何时释放这些资源?如果多个线程可以与一个 pthread 连接,那么每个退出的线程都会有永久的资源泄漏。
  • 那么,终止线程的资源(返回值)会一直保存在内存中,直到 FIRST 线程实际加入并声明它?就像先到先得一样?
  • 不完全。它是“先到先得,如果其他人后来来了,那就得付钱了”。
  • 我可以说原因是什么,但它们可能是令人不快的解决方法,例如 pthread_detach 并且可能会找到一些析构函数或释放的锁以供选择。

标签: multithreading pthreads posix pthread-join


【解决方案1】:

Posix pthread 和 Windows 内核对象之间存在巨大差异(我公然假设您熟悉)。我发现它有令人不快的限制,你只提到了一个。除了当前的实现细节之外,没有真正的技术原因(是的,线程状态在加入后没有保存在内存中,但为什么呢?)。另一个非常令人不快的限制是无法在一次调用中加入多个线程 - 这可能会导致线程上的多路复用。

尽管如此,每天都有数以百万计的基于 pthread 的程序运行,因此这些限制并不是一个阻碍。但事实上,如果没有这些,某些任务会更容易执行。

【讨论】:

  • 就像不是所有的语言都有自动垃圾回收一样,不是所有的线程库都可以跟踪谁可能仍然拥有一个退出线程的句柄。您不妨问一下为什么不允许您 free() 分配两次。
  • @EOF,不。你不需要问'谁还有句柄'。您只是不要在加入时释放手柄。就是这样,简单明了。如果您的应用程序由于线程句柄使用了所有内存而耗尽内存 - 您的应用程序有问题。
  • 我不同意,然后转过来:如果您的线程库无法永久创建新线程 - 您的线程库有问题。
  • 我不是windows编程的粉丝,也是linux和pthreads之类的忠实粉丝,但我必须同意这个说法。这些是 pthread 中令人沮丧的限制。更糟糕的是,我看到很多人为高级语言包装 pthreads,并且由于 pthreads 在这方面而不是必要性提供的灵感或缺乏而导出了这个限制(IE,线程优雅地关闭,所以他们可以弹出他们的状态更改为与管理线程互斥的队列)。
【解决方案2】:

我相信技术原因是 pthread_join 是一个 POSIX 标准,对于多线程,它试图只为实现者指定必要的原语。任何更丰富的语义都会引入更昂贵的实现,并且可能会引入更困难的 API。

确实,POSIX 已经认为这个函数是一种便利,而不是一种原语,以支持一个非常非常常见的用例:一个线程等待另一个线程的终止。

POSIX.1-2008 pthread_join RATIONALE 的第一段有点长,但有很多密切的观察:

pthread_join() 函数是一种便利,已被证明在多线程应用程序中很有用。如果没有通过将额外状态作为参数的一部分传递给start_routine(),程序员确实可以模拟这个函数。终止线程将设置一个标志以指示终止并广播作为该状态一部分的条件;加入线程将等待该条件变量。虽然这种技术允许线程等待更复杂的条件(例如,等待多个线程终止),但等待单个线程终止被认为是广泛有用的。此外,包含 pthread_join() 函数绝不会阻止程序员编写如此复杂的等待。因此,虽然这不是一个原语,但在这卷 POSIX.1-2008 中包含 pthread_join() 被认为是有价值的。

【讨论】:

  • 感谢文档中的具体提及。了解到 pthread_join 的存在是为了方便(因为您可以使用其他技术实现更复杂的等待)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多