提问人:Florin Zamfir 提问时间:10/22/2023 最后编辑:Florin Zamfir 更新时间:10/23/2023 访问量:40
pthread 在释放锁之前被取消
pthread gets cancelled before releasing locks
问:
我对 C 中的多线程仍然很陌生。我编写了一个简单的程序,可以执行以下操作:
main 函数启动多个线程,每个线程都等待使用条件变量设置标志。之后,main 函数启动另一个设置标志的线程,并通过设置标志通知所有线程。start
pthread_cond_broadcast()
start_routine
等待设置标志的线程(此处称为工作线程):
void* workerThread()
{
pthread_mutex_lock(&start_flag_mutex);
while(!start_flag)
{
pthread_cond_wait(&start_flag_condition, &start_flag_mutex);
}
pthread_mutex_unlock(&start_flag_mutex);
//Do some work here...
}
start_routine
广播更改的线程:
void* starterThread()
{
pthread_mutex_lock(&start_flag_mutex);
start_flag = true;
pthread_cond_broadcast(&start_flag_condition);
pthread_mutex_unlock(&start_flag_mutex);
}
在 main 函数启动所有线程后,它会按此顺序加入工作线程和起始线程。所有 pthread 原语在正确使用之前都会初始化,并在正确使用后销毁。在大约 1/10 的运行中,我的程序卡在等待条件的工作线程中。
我的问题是:拥有共享资源锁(在本例中为标志)的工作线程是否有可能在释放它之前被取消,从而导致其他人永远等待?如果是这样,我能做些什么来预防它?
编辑:为清楚起见,工作线程被取消,然后在完成工作后加入主函数。
for (size_t i = 0; i < NUM_WORKERS; ++i)
{
pthread_cancel(worker_tids[i]);
pthread_join(worker_tids[i], NULL);
}
答:
-2赞
Heath Morgan
10/22/2023
#1
在我看来,这确实是可能的。如果工作线程获得第一个线程,它将阻止启动线程继续通过锁定,因此启动线程将永远无法继续到它可以设置 .start_flag_mutex
start_flag = true
编辑重新阅读后,我不确定我是否正确理解了您的问题。我把它解释为一个关于你是否会在启动时陷入僵局的问题。
评论
2赞
Solomon Slow
10/22/2023
如果工作线程获得第一个,它将测试该标志,并发现该标志为 ,然后它将调用 ,这将在调用期间解锁互斥锁。start_flag_mutex
false
pthread_cond_wait(&start_flag_condition,&start_flag_mutex)
0赞
Heath Morgan
10/22/2023
我纠正了,我不明白到底在做什么,但仔细阅读文档确实说互斥锁已解锁,然后在函数返回时再次锁定。pthread_cond_wait
3赞
Heath Morgan
10/22/2023
同样重要的是要注意,所有这些方法都有一个返回值,应检查该值以处理异常情况。
评论
void *f(void *)
void *