26

How do I determine if a detached pthread is still alive ?

I have a communication channel with the thread (a uni-directional queue pointing outwards from the thread) but what happens if the thread dies without a gasp?

Should I resign myself to using process signals or can I probe for thread liveliness somehow?

lornova
  • 6,667
  • 9
  • 47
  • 74
jldupont
  • 93,734
  • 56
  • 203
  • 318

3 Answers3

20

For a joinable (i.e NOT detached) pthread you could use pthread_kill like this:

int ret = pthread_kill(YOUR_PTHREAD_ID, 0);

If you get a ESRCH value, it might be the case that your thread is dead.

However this doesn't apply to a detached pthreads because after it has ended its thread ID can be reused for another thread.

From the comments:

The answer is wrong because if the thread is detached and is not alive, the pthread_t is invalid. You can't pass it to pthread_kill. It could, for example, be a pointer to a structure that was freed, causing your program to crash. POSIX says, "A conforming implementation is free to reuse a thread ID after its lifetime has ended. If an application attempts to use a thread ID whose lifetime has ended, the behavior is undefined." – Thanks @DavidSchwartz

lornova
  • 6,667
  • 9
  • 47
  • 74
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • 5
    The problem with that is the `YOUR_PTHREAD_ID` might have been recycled for another thread in the mean time since it was detached. So it should rather be: __If you get ESRCH, your thread is dead, otherwise you can't be sure__ (unless you know the ID's of newly created threads). – RedGlyph Nov 07 '09 at 14:53
  • @RedGlyph: this is a very typical case of identifier recycling conundrum. In my case, I am willing to live with the small probability of collision it incurs because I'll be polling on a reasonable frequency. – jldupont Nov 07 '09 at 15:03
  • 8
    If your thread is joinable, the thread id **cannot be reused** by the implementation until it has been joined with `pthread_join`. – R.. GitHub STOP HELPING ICE Dec 31 '10 at 04:12
  • 2
    Because the question states that it is a detached thread, its termination will free resources and the thread id will no longer be valid after that. As karsten says, calling pthread_kill on that thread id would then result in undefined behavior. It is not just an issue if the thread id is recycled; the program may crash or do anything else if passed an invalid thread id. So this answer is not only incorrect but dangerous. – mark4o Jan 17 '12 at 19:16
  • @PabloSantaCruz I've just tested your method and got an error: "Use of uninitialised value of size 4" when trying to `pthread_kill` an uninitialized thread... – Kolyunya Sep 30 '12 at 14:18
  • @DavidSchwartz: hi David. I can delete the answer. No problem. But I'd like to learn. Could you please elaborate on why the answer is 100% wrong? Thanks! – Pablo Santa Cruz Feb 01 '13 at 10:50
  • 3
    @PabloSantaCruz You can't delete an accepted answer. The answer is wrong because if the thread is detached and is not alive, the `pthread_t` is invalid. You can't pass it to `pthread_kill`. It could, for example, be a pointer to a structure that was freed, causing your program to crash. [POSIX says](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_02), "*A conforming implementation is free to reuse a thread ID after its lifetime has ended. If an application attempts to use a thread ID whose lifetime has ended, the behavior is undefined.*" – David Schwartz Feb 01 '13 at 18:25
9

This question assumes a design with an unavoidable race condition.

Presumably, you plan to do something like this:

  1. Check to see if thread is alive
  2. Wait for message from thread

The problem is that this sequence is not atomic and cannot be fixed. Specifically, what if the thread you are checking dies between step (1) and step (2)?

Race conditions are evil; rare race conditions doubly so. Papering over something 90% reliable with something 99.999% reliable is one of the worst decisions you can make.

The right answer to your question is "don't do that". Instead, fix your application so that threads do not die randomly.

If that is impossible, and some thread is prone to crashing, and you need to recover from that... Then your design is fundamentally flawed and you should not be using a thread. Put that unreliable thing in a different process and use a pipe to communicate with it instead. Process death closes file descriptors, and reading a pipe whose other end has been closed has well-defined, easily detected, race-free behavior.

Nemo
  • 70,042
  • 10
  • 116
  • 153
5

It is probably undefined behaviour when you send a signal to an already dead thread. Your application might crash. see http://sourceware.org/bugzilla/show_bug.cgi?id=4509 and http://udrepper.livejournal.com/16844.html

karsten
  • 51
  • 1
  • 1