pthread 在释放锁之前被取消

pthread gets cancelled before releasing locks

提问人:Florin Zamfir 提问时间:10/22/2023 最后编辑:Florin Zamfir 更新时间:10/23/2023 访问量:40

问:

我对 C 中的多线程仍然很陌生。我编写了一个简单的程序,可以执行以下操作:

main 函数启动多个线程,每个线程都等待使用条件变量设置标志。之后,main 函数启动另一个设置标志的线程,并通过设置标志通知所有线程。startpthread_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);
}
c 多线程 pthreads 锁定 争用条件

评论

0赞 Shawn 10/22/2023
你可能想要一个屏障
1赞 Solomon Slow 10/22/2023
回复,“是否有可能工作线程......被取消了......?你的意思是“取消”和“被杀”一样?“终止了?”很难回答这个问题,因为您还没有展示整个程序。你展示的任何内容都不会杀死线程,但程序中的其他东西可以做到这一点吗?这取决于您的程序中的其他内容。
0赞 Solomon Slow 10/22/2023
P.S.,为什么起始线程需要是一个不同的线程?为什么主线程不能启动其他线程?P.P.S.,你构建的东西有一个名字。它被称为“旋转门”。这些线程一个接一个地“穿过”它,就像人们在运动场上穿过旋转门一样。而且,它可以“锁定”或“解锁”,就像体育场馆的旋转门一样。问题是,为什么?为什么你希望“worker”线程几乎同时启动?让某些线程比其他线程早几毫秒启动有什么害处?
2赞 ikegami 10/22/2023
您发布的代码应该可以正常工作。请提供问题的演示,而不是可能不相关的片段。
0赞 John Bollinger 10/23/2023
您的线程函数不正确。pthreads 线程的入口点函数必须完全具有签名。特别是在这里,他们必须接受 类型的参数,即使他们忽略它。我不认为这实际上是你行为不端的原因,但它需要解决。void *f(void *)void *

答:

-2赞 Heath Morgan 10/22/2023 #1

在我看来,这确实是可能的。如果工作线程获得第一个线程,它将阻止启动线程继续通过锁定,因此启动线程将永远无法继续到它可以设置 .start_flag_mutexstart_flag = true

编辑重新阅读后,我不确定我是否正确理解了您的问题。我把它解释为一个关于你是否会在启动时陷入僵局的问题。

评论

2赞 Solomon Slow 10/22/2023
如果工作线程获得第一个,它将测试该标志,并发现该标志为 ,然后它将调用 ,这将在调用期间解锁互斥锁。start_flag_mutexfalsepthread_cond_wait(&start_flag_condition,&start_flag_mutex)
0赞 Heath Morgan 10/22/2023
我纠正了,我不明白到底在做什么,但仔细阅读文档确实说互斥锁已解锁,然后在函数返回时再次锁定。pthread_cond_wait
3赞 Heath Morgan 10/22/2023
同样重要的是要注意,所有这些方法都有一个返回值,应检查该值以处理异常情况。