如果我有一个初始化的pthread_barrier_t,什么时候可以安全地销毁它?以下示例是否安全?
pthread_barrier_t barrier;
...
int rc = pthread_barrier_wait(b);
if (rc != PTHREAD_BARRIER_SERIAL_THREAD && rc != 0){
perror("pthread_barrier_wait");
exit(1);
}
if (id == 0){
if(pthread_barrier_destroy(&(threads[t_root].info.tmp_barrier))){
perror("pthread_barrier_destroy");
exit(1);
}
}
答案 0 :(得分:5)
pthread_barrier_wait()
返回后,所有线程都会遇到障碍并且正在继续。由于只有一个线程被赋予PTHREAD_BARRIER_SERIAL_THREAD
返回值,因此可以安全地使用它来有条件地包装破坏代码,如下所示:
int rc = pthread_barrier_wait(&b)
if ( rc == PTHREAD_BARRIER_SERIAL_THREAD )
{
pthread_barrier_destroy(&b);
}
此外,请注意pthread_barrier_destroy()
如果屏障正在使用(即另一个帖子调用EBUSY
),则会返回pthread_barrier_wait()
的结果。
答案 1 :(得分:2)
接受的答案不正确。 PTHREAD_BARRIER_SERIAL_THREAD的返回值并不意味着可以安全地破坏屏障。
在破坏屏障之前,您需要额外的同步。
问题在于,当其他线程正在离开屏障时,可能会发生破坏调用。由于futex系统调用可能具有“错误唤醒”的事实,因此这些线程需要检查屏障的状态。如果屏障使用的内存从其下方释放出来,则会发生未定义的行为。
因此,销毁线程需要等待,直到所有其他线程完成退出屏障为止。为了做到这一点,需要额外的同步。 Source with alternative implementation using pthread_cond
在此问题中,用户正在执行与示例代码相同的逻辑。 https://groups.google.com/forum/#!topic/thread-sanitizer/81idLTirikQ