gpt4 book ai didi

c++ - 为什么在极少数情况下 pthread_exit() 在 pthread_detach() 之后调用时会导致 SEGV?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:02 27 4
gpt4 key购买 nike

我在调用 pthread_join() 时遇到了一个 C++ 无法轻易重现的 SEGV(大约每 100,000 次测试运行中就会出现一次),因为我的应用程序正在关闭。我检查了 errno 的值,它是零。这是在 Centos v4 上运行的。

在什么情况下 pthread_join() 会得到一个 SEGV?这可能是某种竞争条件,因为它非常罕见。有人建议我不应该调用 pthread_detach() 和 pthread_exit(),但我不清楚原因。

我的第一个工作假设是 pthread_join() 被调用,而 pthread_exit() 仍在另一个线程中运行,这不知何故导致了 SEGV,但是许多人表示这不是问题。

在应用程序退出期间在主线程中获取 SEGV 的失败代码大致如下所示(为简洁起见省略了错误返回代码检查):

// During application startup, this function is called to create the child thread:

return_val = pthread_create(&_threadId, &attr,
(void *(*)(void *))initialize,
(void *)this);

// Apparently this next line is the issue:
return_val = pthread_detach(_threadId);

// Later during exit the following code is executed in the main thread:

// This main thread waits for the child thread exit request to finish:

// Release condition so child thread will exit:
releaseCond(mtx(), startCond(), &startCount);

// Wait until the child thread is done exiting so we don't delete memory it is
// using while it is shutting down.
waitOnCond(mtx(), endCond(), &endCount, 0);
// The above wait completes at the point that the child thread is about
// to call pthread_exit().

// It is unspecified whether a thread that has exited but remains unjoined
// counts against {PTHREAD_THREADS_MAX}, hence we must do pthread_join() to
// avoid possibly leaking the threads we destroy.
pthread_join(_threadId, NULL); // SEGV in here!!!

在退出时加入的子线程运行以下代码,该代码从上面在主线程中调用 releaseCond() 的点开始:

// Wait for main thread to tell us to exit:
waitOnCond(mtx(), startCond(), &startCount);

// Tell the main thread we are done so it will do pthread_join():
releaseCond(mtx(), endCond(), &endCount);
// At this point the main thread could call pthread_join() while we
// call pthread_exit().

pthread_exit(NULL);

该线程似乎正常启动,在应用程序启动期间创建它的过程中没有产生错误代码,并且线程正确地执行了它的任务,这在应用程序退出前花费了大约五秒钟。

什么可能导致这种罕见的 SEGV 发生以及我应该如何针对它进行防御性编程。一种说法是我对 pthread_detach() 的调用是问题所在,如果是这样,我的代码应该如何更正。

最佳答案

假设:

  1. pthread_create 返回零(您正在检查它,对吧?)
  2. attr 是一个有效的 pthread_attr_t 对象(您如何创建它?为什么不直接传递 NULL 呢?)
  3. attr 没有指定线程是detached创建的
  4. 您没有在其他地方的线程上调用 pthread_detachpthread_join

...那么 pthread_join 是“不可能”失败的,并且您可能遇到其他内存损坏或运行时中的错误。

[更新]

pthread_detach 的基本原理部分说:

The *pthread_join*() or *pthread_detach*() functions should eventually be called for every thread that is created so that storage associated with the thread may be reclaimed.

虽然它没有说它们是相互排斥的,pthread_join documentation指定:

The behavior is undefined if the value specified by the thread argument to *pthread_join*() does not refer to a joinable thread.

我很难找到说分离线程不可连接的确切措辞,但我很确定这是真的。

因此,要么调用 pthread_join 要么调用 pthread_detach,但不能同时调用。

关于c++ - 为什么在极少数情况下 pthread_exit() 在 pthread_detach() 之后调用时会导致 SEGV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11442601/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com