在终止线程上调用pthread_cancel()是否安全?

dom*_*ine 11 c posix pthreads

我想知道调用pthread_cancel()终止线程是否安全.我在手册页中找不到任何提示.提前感谢任何提示.

编辑:也许我不够准确.我不是在讨论由早期的pthread_cancel()终止的线程,而是关于只是从它们的线程函数返回的线程.

cni*_*tar 10

我认为它需要安全,否则pthread_cancel会出现问题(旁边无法使用).

实际上,如果它不安全,pthread_cancel通过检查线程是否存活(并确保它保持活着直到你取消它),每次调用都必须非常复杂.一个简单的"你还在那里"是不行的.

总之,如果线程终止,我相信pthread_cancel 必须是安全的.当然,对于已终止且已连接的线程,情况可能并非如此.

  • 简单规则:pthread_t在线程终止(如果已分离)或已连接(如果不是)时有效.这意味着只有当您知道它没有终止时,您才能安全地pthread_cancel一个分离的线程.你可以安全地pthread_cancel一个非分离的线程,只要你知道它没有pthread_join'ed. (6认同)

osg*_*sgx 7

实际上一个暗示:

错误最高

  ESRCH  No thread with the ID thread could be found.
Run Code Online (Sandbox Code Playgroud)

MKS给出了一个有点其他描述:

ESRCH

线程没有在进程中指定当前正在运行的线程.

OpenGroup建议:

如果实现在生命周期结束后检测到使用了线程ID,则建议该函数失败并报告[ESRCH]错误.

UPDATE

在NPTL中,有一个双重取消检查或退出后取消:

  /* We are canceled now.  When canceled by another thread this flag
     is already set but if the signal is directly send (internally or
     from another process) is has to be done here.  */
  int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;

  if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
    /* Already canceled or exiting.  */
    break;
Run Code Online (Sandbox Code Playgroud)

因此,退出后的第二次取消或取消将是死线的noop.

exiting_bitmask由__do_cancel设置:

/* Called when a thread reacts on a cancellation request.  */
static inline void
__attribute ((noreturn, always_inline))
__do_cancel (void)
{
  struct pthread *self = THREAD_SELF;

  /* Make sure we get no more cancellations.  */
  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
Run Code Online (Sandbox Code Playgroud)

__do_cancel既是对异步取消的反应,也是对pthread_exit的反应

void
__pthread_exit (value)
     void *value;
{
  THREAD_SETMEM (THREAD_SELF, result, value);

  __do_cancel ();
Run Code Online (Sandbox Code Playgroud)

  • 是的,但即使线程终止,也可能会调用`pthread_join`,所以**当一个线程结束其ID时仍然有效**. (2认同)
  • domachine,来自[这个答案]的链接(http://stackoverflow.com/questions/6371844/calling-pthread-cancel-on-a-joined-thread-causes-segfault-under-linux/6373108#6373108)是[标准IEEE Std 1003.1-2008](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_02),其中说明:如果线程终止,则线程ID的生命周期结束detachstate属性设置为PTHREAD_CREATE_DETACHED,或者是否已为该线程调用pthread_detach()或pthread_join(). (2认同)
  • @domachine是的,我知道.我只是在发表评论.这是一个很好的问题,提供非常丰富的答案. (2认同)
  • 尽管文档可能对生命周期和有效线程 id 有任何说明,但在我的普通 Debian Wheezy 系统上,在终止的线程上调用 `pthread_cancel` 会导致返回值 -1 并且 `errno` 设置为 `ESRCH`。 (2认同)