Skip to content
Advertisement

Race condition on pthread_kill()?

Linux manual for pthread_kill() has the following paragraph:

POSIX.1-2008 recommends that if an implementation detects the use of a thread ID after the end of its lifetime, pthread_kill() should return the error ESRCH. The glibc implementation returns this error in the cases where an invalid thread ID can be detected. But note also that POSIX says that an attempt to use a thread ID whose lifetime has ended produces undefined behavior, and an attempt to use an invalid thread ID in a call to pthread_kill() can, for example, cause a segmentation fault.

The problem is, between checking the thread ID is valid and issuing the pthread_kill(), the thread might have terminated. Is it inherently unsafe to use pthread_kill(), as there is always a race condition that can turn into a undefined behavior?

How to ensure thread ID will be valid?

Advertisement

Answer

Race condition on pthread_kill()?

When the thread is detached, always. But if thread ID is valid, no.

Is it inherently unsafe to use pthread_kill(), as there is always a race condition that can turn into a undefined behavior?

No, not always.

How to ensure thread ID will be valid?

From POSIX thread ID:

The lifetime of a thread ID ends after the thread terminates if it was created with the detachstate attribute set to PTHREAD_CREATE_DETACHED or if pthread_detach() or pthread_join() has been called for that thread.

Otherwise it’s valid. So when the thread is not detached nor joined, thread ID is just valid and you always at any time can call pthread_kill() with it.

Generally, you should stop using a thread ID after pthread_detach or pthread_join. It’s like free() in malloc() – you can’t use memory allocated by malloc() after free(). The same way you can’t use thread ID after detaching or joining, the thread ID just becomes invalid. Just with pthread_detach it becomes invalid “later”, but you don’t know when, so you can’t use it anyway (well, unless you write your own synchronization). It might become invalid right after the call to pthread_detach. If you intent to do anything with a thread ID, do not detach and do not join it.

The call to pthread_kill with “inactive thread” (non-detached non-joined thread that terminated) is valid – the thread ID is still valid. We can read from pthread_kill posix:

Existing implementations vary on the result of a pthread_kill() with a thread ID indicating an inactive thread (a terminated thread that has not been detached or joined). Some indicate success on such a call, while others give an error of [ESRCH]. Since the definition of thread lifetime in this volume of POSIX.1-2017 covers inactive threads, the [ESRCH] error as described is inappropriate in this case. In particular, this means that an application cannot have one thread check for termination of another with pthread_kill().

FUTURE DIRECTIONS

A future version of this standard may require that pthread_kill() not fail with [ESRCH] in the case of sending signals to an inactive thread (a terminated thread not yet detached or joined), even though no signal will be delivered because the thread is no longer running.

The FUTURE DIRECTIONS looks like it’s prefering that pthread_kill() with an inactive thread should just succeed and return 0. I personally like the ESRCH error in such case.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement