На самом деле есть подсказка:
ОШИБКИ top
ESRCH No thread with the ID thread could be found.
А МКС дает немного другое описание:
ESRCH
поток не указывает текущий запущенный поток в процессе.
OpenGroup рекомендует:
Если реализация обнаруживает использование идентификатора потока после окончания срока его службы, рекомендуется, чтобы функция завершилась сбоем и сообщила об ошибке [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;
Итак, вторая отмена или отмена после выхода будет 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 ();