Безопасно ли вызывать pthread cancel () в завершенном потоке?

Мне интересно, безопасно ли звонить pthread_cancel() на завершенном потоке. Я не мог найти никаких намеков на странице руководства. Заранее спасибо за любые подсказки.

Edit: возможно, я был недостаточно точен. Я не говоря о потоках, завершенных более ранним pthread_cancel (), но о потоках, которые просто вернулись из своей функции потока.

3 ответов


Я думаю, что это должен чтобы быть в безопасности, или pthread_cancel было бы проблематично (рядом с непригодным для использования).

действительно, если это не будет безопасно, каждый вызов pthread_cancel должно быть чрезвычайно сложно, проверяя, что поток жив (и гарантируя, что он остается живым, пока вы не отмените его). Простое "ты еще здесь?" не годится.

В заключение, я верю pthread_cancel должны будьте в безопасности, если поток завершен. Конечно, это может быть не случай для прерванной и присоединенной нити.


здесь намек на самом деле:

ошибки top

  ESRCH  No thread with the ID thread could be found.

и MKS дает немного другое описание:

ошибкой esrch

thread не указывает текущий поток в процессе.

OpenGroup рекомендует:

если реализация обнаруживает использование идентификатора потока после окончания его срока службы, это рекомендуется, чтобы функция завершилась ошибкой и сообщила об ошибке [ESRCH].

обновление

в 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;

Итак, вторая отмена или отмена после выхода будет 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);

__do_cancel-это реакция на асинхронная отмена и для pthread_exit

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

  __do_cancel ();

нет, небезопасно вызывать pthread_cancel () в потоке, который был завершен.

причина в том, что реализация может повторно использовать идентификатор потока завершенного потока для другого потока и вызов "pthread_cancel()" на этом TID может вызвать завершение в потоках, которые не должны быть завершены или неопределенное поведение.