3

I know I can create a pthread with joinable attribute set, but once created,

  1. am I right that I can also change that pthread to a detached pthread?
  2. If that's the case, how can I check if a pthread is joinable? And how can I change a pthread from joinable to detached?
SergeyA
  • 61,605
  • 5
  • 78
  • 137
james
  • 1,107
  • 14
  • 29
  • 1
    May be worth mentioning that POSIX considers `pthread_join` a ["convenience"](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html#tag_16_432_08) function and not a necessity. In other words, you can redesign your way out of this question if the answers aren't what you like. – pilcrow Jan 07 '16 at 23:06

2 Answers2

1
  1. Yes, you can. Just call pthread_detach() on the thread.
  2. You have several options.

a. If you have launched your thread with specified pthread_attr, and this pthread_attr is still around, you can reliably check the joinable state by calling pthread_attr_getdetachstate. If pthread_attr is not available, and you are on Linux, you can requery for the attribute by calling pthread_getattr_np - note, that _np means non-Posix, so this will likely be Linux-only.

b. You can simply try joining it. A pthread which is not joinable usually will return EINVAL. This is not standard with POSIX, but something you can rely upon with, for example, Linux - as well as Solaris and likely other major systems.

c. The easiest option is to simply keep track of your threads yourself, so that you will always know if the particular thread is joinable simply by checking your program state.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 4
    You can't necessarily depend on `EINVAL` being returned. from the POSIX spec for `pthread_join()`: "The behavior is undefined if the value specified by the thread argument to pthread_join() does not refer to a joinable thread". – Michael Burr Jan 07 '16 at 22:16
  • @MichaelBurr, the same page says: 'EINVAL thread is not a joinable thread.' Of course, it must be joinable, otherwise the function will return failure. On Linux, EINVAL for non-joinable threads can be relied upon. – SergeyA Jan 07 '16 at 22:18
  • I will still edit my answer to provide better guidance. – SergeyA Jan 07 '16 at 22:19
  • sorry - I edited my comment to remove the Linux manpage reference while you were responding. I suppose my comment may not apply to Linux, but should if strict POSIX portability is desired. – Michael Burr Jan 07 '16 at 22:21
  • @MichaelBurr, I have edited my answer, hopefully it is in a better shape now. – SergeyA Jan 07 '16 at 22:26
  • @SergeyA It says that *if* it returns `EINVAL`, then that means the thread is not joinable. It says *nothing* about the other way around. And when you say, "on Linux", you mean on *current* Linux systems that you know of, right? – David Schwartz Jan 07 '16 at 23:52
  • Note that at least some versions of the Linux man page list _two_ conditions for EINVAL: if the thread is not joinable (i.e., is not joinable by anyone) as well as if the thread is already being waited on by another's join (i.e., is not joinable _by me_). – pilcrow Jan 08 '16 at 05:05
  • Thanks guys for your inputs. For option a, if I use pthread_getattr_np(), can I rely on it even if the thread does not exist any more, e.g. done its job. – james Jan 08 '16 at 11:47
  • 1
    If the thread does not exist any more, any attempt to pass its `pthread_t` to one of the `pthread` functions is unsafe. It's the same thing as a `FILE*` after you pass it to `fclose`. – David Schwartz Jan 08 '16 at 22:39
  • Note also that `Attempting to detach an already detached thread results in unspecified behavior`. So, point 1 is just not right. – Zaxter Apr 23 '17 at 14:28
1

am I right that I can also change that pthread to a detached pthread?

Yes, that's correct.

If that's the case, how can I check if a pthread is joinable?

You can't, and asking to do so doesn't make any sense. Unless you have a joinable pthread that you know for a fact has not yet been joined, there is no pthread for you to check. A detached, or joined, pthread may no longer exist, so there is no "a pthread" for you to check on.

There is no way to check whether a thing that might or might not actually be a thread is a thread. People who suggest otherwise are asking you to rely on behavior that is not guaranteed, and that would be extremely foolish.

And how can I change a pthread from joinable to detached?

You can detach it, or it can detach itself, at any time by calling pthread_detach. The most common pattern is that something owns the thread, and that thing is responsible for joining the thread when it's finished (or shutting down). If you just want a thread to run until it's done without any kind of supervision or ownership, detach it or have it detach itself.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278