I have a multi-thread application where each thread has a helper thread that helps the first one to accomplish a task. I would like that when a thread is terminated (likely calling exit) the helper thread is terminated as well.
I know that there is the possibility to use exit_group, but this system call kills all threads in the same group of the calling thread. For example, if my application has 10 threads (and therefore 10 additional helper threads) I would like that only the thread and the helper thread associated is terminated, while the other threads keep on running.
My application works exclusively on Linux.
How can I have this behavior?
Reading around about multithreading I got a bit confused about the concept of thread group and process group in Linux. Are these terms referring to the same thing?
Precisely, the process group (and perhaps the thread group) is the pid retrieved by one of the following calls :
pid_t getpgid(pid_t pid);
pid_t getpgrp(void); /* POSIX.1 version */
pid_t getpgrp(pid_t pid); /* BSD version */
You are a bit adrift here. Forget exit_group, which these days is the same as exit on linux is not what you are looking for. Similarly the various get-pid calls aren't really what you want either.
The simplest (and usually best) way to handle this is have each primary thread signal its helper thread to shut down and then pthread_join it - or not if it is detached.
So something like:
(a) primary work thread knows - however it knows - its work is done.
(b) signals helper thread via a shared switch or similar mechanism
(c) helper thread periodically checks flag, cleans up and calls pthread_exit
(d) primary worker thread calls pthread_join (or not) on dead helper thread
(e) primary worker cleans up and calls pthread_exit on itself.
There are a lot of variations on that but that's the basic idea. Beyond that you get into things like pthread_cancel and areas you may want to avoid if you don't absolutely require them (and the potential headaches).
Related
In the POSIX thread interface, pthread_join(thread) can be used to block until the specified thread exits.
Is there a similar function that will allow execution to block until any child thread exits?
This would be similar to the wait() UNIX system call, except be applicable for child threads, not a processes
I don't think this is directly possible from pthreads per se, but you can work around it fairly easily.
Using the pthreads API, you can use pthread_cond_wait and friends to set up a "condition" and wait on it. When a thread is about to exit, signal the condition to wakeup the waiting thread.
Alternatively, another method is to create a pipe with pipe, and when a thread is going to exit, write to the pipe. Have the main thread waiting on the other end of the pipe with either select, poll, epoll, or your favorite variant thereof. (This also allows you to wait simultaneously on other FDs.)
Newer versions of Linux also include "eventfds" for doing the same thing, see man eventfd, but note this is only recently added. Note that is isn't POSIX, it's Linux-only, and it's only available if you're reasonably up-to-date. (2.6.22 or better.)
I've personally always wondered why this API wasn't designed to treat these things similar to file descriptors. If it were me, they'd be "eventables", and you could select files, threads, timers...
I don't think there's any function in the POSIX thread interface to do this.
You'd need to create your own version of it - e.g. an array of flags (one flag per thread) protected by a mutex and a condition variable; where just before "pthread_exit()" each thread acquires the mutex, sets its flag, then does "pthread_cond_signal()". The main thread waits for the signal, then checks the array of flags to determine which thread/s to join (there may be more than one thread to join by then).
You need to implement a customize one by pthread conditional variable: pthread_cond_wait(), pthread_cond_signal()/pthread_cond_broadcast().
What's the recycle strategy of Linux thread ID ?
Linux process ID will not be reused immediately unless new PID get the max limitation and being rewinded.
When I use pthread_self() to get thread id, I got TIDs like 1028, 1034. I guess it is the inner "serial number" of threads in a process. So I guess it would be more appropriate to use a thread id recycle strategy like PID recycle strategy.
But I am not quite sure whether it is true as to Linux pthread implementation.
A threaded linux process has
an OS pid shared by all threads within the process - use getpid
each thread within the process has its own OS thread id - use gettid
a pthreads thread id used internally by pthreads to identify threads when making various pthread related calls - use pthread_self and similar.
It can't be determine from your question if you trying to implement a "recycle strategy" or why you think you need to do so.
Edit
As an idle curiosity you can look through the linux pthread code but technically you have no reason to care. The POSIX spec basically just says the thread id is guaranteed to be unique within a process and is free to be reused after a thread dies.
Although implementations may have thread IDs that are unique in a system, applications should only assume that thread IDs are usable and unique within a single process. The effect of calling any of the functions defined in this volume of IEEE Std 1003.1-2001 and passing as an argument the thread ID of a thread from another process is unspecified. A conforming implementation is free to reuse a thread ID 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.
In linux threads are implemented as processes (with shared memory and other stuff)
so the kernel thread ids (the ones you get through gettid()) are really process ids.
This is also indicated by the fact that the id of first thread of a process and that process' id are one and the same.
Now i don't know exactly what is the pid-allocation algorithm employed by the linux kernel, but i believe it makes some effort to avoid rapid pid reuse (i think i have read about that somewhere but cant remember).
Note that those are the kernel thread ids (returned by the syscall gettid()), which is different thing from the "pthread_t" (returned by the library function pthread_self()).
While both can be used to uniquely identify threads, the former is linux-specific, so if your code needs to be portable you better avoid it (or use #ifdef-s).
I'm going to write a program in which the main thread creates new thread and then the new thread creates a child process. Since I have a hard time keeping track of the new thread and forked process, I'd like to gain a wise answer from someone.
My question is
1. Does a created process in a thread start to execute codes after pthread_create?
2. If 1 is not, where does the forked process start from if a call of fork in a thread occurs?
Thank you for reading my question.
Some of this is a bit OS-dependent, as different systems have different POSIX thread implementations and this can expose internals.
POSIX offers pthread_atfork as a somewhat blunt instrument for dealing with some of the issues, but it still looks pretty messy to me.
If your system uses a one-to-one map between "user land thread" and "kernel thread" using clone or rfork to achieve proper user-space sharing of data between threads, then fork will merely duplicate the (single) thread that calls it. However, if your system has a many-to-many style mapping (so that one user process is handling multiple threads, at least before they enter into blocking syscalls), fork may internally duplicate multiple threads. POSIX says it should look like it only duplicated one thread, so that's not supposed to be visible, but I'm not sure how well all systems implement this.
There's some general advice at http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them (Linux-centric, obviously, but still useful).
Is there some particular reason you want to fork inside a thread but not exec? In general, if you just want to run more code in parallel, you just spin off yet another thread (i.e., once you choose to run any threads, you do everything in threads, except if you have to fork for exec; if the exec fails, just _exit).
I am trying to checkpoint a multithreaded application. For single threaded applications, forking a process as a checkpoint is an efficient technique. However, there is no such thing as a mulithreaded fork. Any idea of how to implement your own mulithreaded fork? Any reference to such work will be greatly appreciated.
There is no portable way to implement a variant of fork that preserves all threads using the interfaces provided by POSIX. On some systems such as Linux, you could implement a highly non-portable, highly fragile version of this either:
using ptrace to trace all threads (to stop them), then making new kernel threads in the child process to duplicate each thread in the parent and assigning them the original stack addresses, instruction pointers, register values, etc. You'd also need to patch up the thread descriptors to know their new kernelspace thread ids, and you'd need to avoid race conditions in this if the thread was in the middle of querying its thread id.
using vfork followed by SIGSTOP to halt the parent process and give yourself a chance to recreate its thread state without things changing under you. This seems possible but sufficiently difficult I'd get a headache trying to go into detail, I think...
(newly added) catch each thread in signal handlers before forking, and save the ucontext_t argument to the signal handler. Then fork and make new kernel threads (using clone), have them signal themselves, then overwrite the ucontext_t the signal handler gets to have the signal handler return back into the context of the original thread you're trying to duplicate. Of course this would all require very clever synchronization...
Alternatively, you could look for a kernel-based "process hibernation" approach to checkpointing that would not be so hackish...
What do you mean by "multithreaded fork"? A function that makes a copy of a multithreaded process, so that the forked process has just as many threads as the old one? A function that makes a new thread which copies the state of the old one?
The latter isn't possible, since the address space is shared. A copy of the current thread's state would be using the current thread's stack, and the new thread and the old thread would fight over the stack.
See also:
Multithreaded fork
fork and existing threads?
In the POSIX thread interface, pthread_join(thread) can be used to block until the specified thread exits.
Is there a similar function that will allow execution to block until any child thread exits?
This would be similar to the wait() UNIX system call, except be applicable for child threads, not a processes
I don't think this is directly possible from pthreads per se, but you can work around it fairly easily.
Using the pthreads API, you can use pthread_cond_wait and friends to set up a "condition" and wait on it. When a thread is about to exit, signal the condition to wakeup the waiting thread.
Alternatively, another method is to create a pipe with pipe, and when a thread is going to exit, write to the pipe. Have the main thread waiting on the other end of the pipe with either select, poll, epoll, or your favorite variant thereof. (This also allows you to wait simultaneously on other FDs.)
Newer versions of Linux also include "eventfds" for doing the same thing, see man eventfd, but note this is only recently added. Note that is isn't POSIX, it's Linux-only, and it's only available if you're reasonably up-to-date. (2.6.22 or better.)
I've personally always wondered why this API wasn't designed to treat these things similar to file descriptors. If it were me, they'd be "eventables", and you could select files, threads, timers...
I don't think there's any function in the POSIX thread interface to do this.
You'd need to create your own version of it - e.g. an array of flags (one flag per thread) protected by a mutex and a condition variable; where just before "pthread_exit()" each thread acquires the mutex, sets its flag, then does "pthread_cond_signal()". The main thread waits for the signal, then checks the array of flags to determine which thread/s to join (there may be more than one thread to join by then).
You need to implement a customize one by pthread conditional variable: pthread_cond_wait(), pthread_cond_signal()/pthread_cond_broadcast().