【发布时间】:2011-10-19 15:07:10
【问题描述】:
在过去的一个问题中,我询问了如何在没有破坏竞赛的情况下实现 pthread 屏障:
How can barriers be destroyable as soon as pthread_barrier_wait returns?
并从 Michael Burr 那里收到了针对流程本地障碍的完美解决方案,但对于流程共享障碍却失败了。后来我们也摸索了一些想法,但始终没有得出令人满意的结论,甚至没有开始涉足资源故障案例。
是否可以在 Linux 上制作满足这些条件的屏障:
- 进程共享(可以在任何共享内存中创建)。
- 在屏障等待函数返回后立即从任何线程取消映射或销毁屏障是安全的。
- 由于资源分配失败而无法失败。
Michael 解决进程共享案例的尝试(请参阅链接的问题)有一个不幸的属性,即必须在等待时分配某种系统资源,这意味着等待可能会失败。并且不清楚当屏障等待失败时调用者可以合理地做什么,因为屏障的全部意义在于在剩余的N-1 线程到达它之前继续进行是不安全的......
内核空间解决方案可能是唯一的方法,但即使这样也很困难,因为信号可能会中断等待而没有可靠的方法来恢复它...
【问题讨论】:
-
我不确定我是否真的理解您的问题,据我所知,NPTL 实现是故障安全的。屏障本身是在外部分配的,它的
pthread_barrier_destroy函数只与最后一个等待者同步。到底是什么问题? -
@Hasturkun:参见 glibc 错误 #13065:sourceware.org/bugzilla/show_bug.cgi?id=13065
-
虽然缺少附件,但似乎描述了在屏障被破坏之前未映射内存的情况。如果我理解正确,那么在销毁屏障之前取消映射屏障永远是不安全的(除非您可以保证没有线程使用屏障,假设您不是最后一个用户)。 NPTL 实现永远不会在没有锁的情况下访问任何东西,
pthread_barrier_destroy需要锁,确保在销毁成功时没有人访问屏障内部(如果任何线程正在等待,它就不会这样做)。 -
只要保留其他可销毁的映射(例如在其他进程中),在屏障被销毁之前取消映射是安全的。这将是进程共享同步对象的标准用法,其中一个进程只需要在固定时间内访问它。
-
如果您可以保证您的进程没有使用它,那将是安全的,在这种情况下,确实不应该有问题。如果您决定在相关函数返回之前释放屏障(或任何其他原语)的底层内存,我认为没有任何理由期待任何类型的行为。您应该在取消映射内存之前同步所有用户,无论是显式地还是通过正确使用
pthread_barrier_destroy。在后一种情况下,您可以稍后重新初始化屏障以供重用。
标签: c linux pthreads posix barrier