【问题标题】:pthread join child thread in both thread function and cancellation handler?pthread 在线程函数和取消处理程序中加入子线程?
【发布时间】:2017-09-04 13:31:43
【问题描述】:

我遇到了以下并发问题的场景,使用 pthread 库实现:

我收到了一个随时可能被取消的话题。当该线程被取消时,它需要取消其子线程,并确保其子线程在终止之前已经被取消。

所以我最终在子线程上调用 pthread_join 两次,一次在线程例程中(因为当线程未取消时,我需要该结果),一次在线程的取消清理处理程序中。

但是,pthread_join 不允许两次加入同一个线程,那么会发生什么?

以下是伪代码:

void CleanupFunc(void* ChildThread)
{
    pthread_cancel(*(pthread_t*)ChildThread);
    pthread_join(*(pthread_t*)ChildThread, NULL);
}

void* ThreadFunc(void* _)
{
    pthread_t ChildThread;
    pthread_cleanup_push(&CleanupFunc, &ChildThread);
    pthread_create(&ChildThread, NULL, &ChildThreadFunc, NULL);
    pthread_join(ChildThread, NULL);
    pthread_cleanup_pop(0);
}

提前致谢!

【问题讨论】:

  • "我需要该结果" 从您显示的代码中,它看起来不像您需要它:pthread_join(ChildThread, NULL);
  • 取消一个线程从来都不是一个好主意。您可能想过度考虑程序的设计。

标签: multithreading unix pthreads pthread-join


【解决方案1】:

但是,pthread_join 不允许两次加入同一个线程,那么会发生什么?

线程不再可连接,因此结果是未定义的行为。

根据POSIX standard documentation for pthread_join()

如果thread 指定的值,则行为未定义 pthread_join() 的参数不引用可连接线程。

【讨论】:

  • 那么我可以假设其中一个 pthread_join 调用会起作用吗?清理处理程序中的那个会起作用吗?
  • @A.Stone 不,你不能假设它会起作用。它几乎肯定不会起作用,即使它看起来起作用,您也可能只是随机加入了一些其他线程。你甚至可能会得到nasal demons
  • 但是pthread_join只有两个,对吧?这是否意味着第一个可以工作,并且(我认为)清理处理程序中的那个是第一个?清理处理程序完成后,线程将终止,第二个 pthread_join 将不起作用。但这是我的猜测,你怎么看?或者你有更好的方法来实现我想做的事情吗?
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2021-04-06
  • 2011-09-27
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多