i'm working with a multi-threaded program (using pthreads) that currently create a background thread (PTHREAD_DETACHED) and then invokes pthread_exit(0). My problem is that the process is then listed as "defunct" and curiously do not seems to "really exists" in /proc (which defeats my debugging strategies)
I would like the following requirements to be met:
the program should run function A in a loop and function B once
given the PID of the program /proc/$pid/exe, /proc/$pid/maps and /proc/$pid/fd must be accessible (when the process is defunct, they are all empty or invalid links)
it must be possible to suspend/interrupt the program with CTRL+C and CTRL+Z as usual
edit: I hesitate changing the program's interface for having A in the "main" thread and B in a spawned thread (they are currently in the other way). Would it solve the problem ?
You can either suspend the execution of the main process waiting for a signal, or don't detach the thread (using the default PHTREAD_CRATE_JOINABLE) waiting for its termination with a pthread_join().
Is there a reason you can't do things the other way round: have the main thread run the loop, and do the one-off task in the background thread?
Not the most elegant design but maybe you could block the main thread before exiting with:
while(1) {
pause();
}
Then you can install a signal handler for SIGINT and SIGTERM that breaks the loop. The easiest way for that is: exit(0) :-).
Related
I've recently had a problem with signals. I'd like to write a program in C which would print anything after a signal is sent to the process. For example: If I send SIGTERM to my process (which is simply running program), I want the program to print out for example, "killing the process denied" instead of killing the process. So how to do that? How to force process to catch and change the meaning of such signal. Also I have a question if there is any possibility to kill the init process (I know it's kind of a stupid question, but I was wondering how linux deals with such a signal, and how would it technically look if I type: sudo kill -9 1.
Don't use the signal handler to print. You can set a variable of type volatile sig_atomic_t instead, and have your main thread check this (see this example).
When your main thread has nothing else to do (which should be most of the time), let it block on a blocking function call (e.g. sleep()) that will wake up immediately when the signal is received (and set errno to EINTR).
C++ gotcha: Unlike the C sleep() function, std::this_thread::sleep_for() (in recent versions of glibc) does not wake up when a signal is received.
Regarding if it's possible to kill pid 1, see this question. The answer seems to be no, but I remember that Linux got very grumpy once I booted with init=/bin/bash and later exited this shell – had to hard reboot.
If you're looking for trouble, better kill pid -1.
i am making a small project which will be incorporated into larger project. basically what it does is keeps track of threads that are created by way of adding them to a main struct which keeps track of what the thread does (its main function) and its pthread_t id. the other struct keeps track of the data to be passed to the function and the element number of where the pthread_t id is stored inside threads[]. its a bit micky mouse and it jumps around a bit but it all works besides when it is time to kill the thread. i get no segfaults and no errors and the program finishes fine, but the thread does not get killed when pthread_kill() is called (the function returns 0 meaning no error and it worked) although the thread continues to run until the main application returns.
pthread_kill() will not kill a thread. The only difference with kill() is that the signal is handled by the designated thread and not handled while that thread has the signal masked (see pthread_sigmask()). A signal like SIGTERM will by default still terminate the entire process.
If you are considering to call pthread_exit() from a signal handler, you should probably use pthread_cancel() instead.
Cancellation is safe if all code that may be cancelled cooperates (or the code that calls it disables cancellation for the time). Most libraries do not care about this, though.
A safer method is to ask the thread to exit without any force, such as by sending a special message to it (if the thread normally processes messages).
Alternatively, don't bother to kill any threads and just call _exit(), _Exit() or quick_exit().
From http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_kill.html
As in kill(), if sig is zero, error checking is performed but no signal is actually sent.
so the following
pthread_kill(threads[i].tID, 0);
Wont actually kill the thread. You need to use an actual signal to kill a thread. A list of signals can be found here:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
"The wait() system call suspends execution of the current process until one of its children terminates" . Waitpid also is similar.
My Question is whether calling wait() from one thread will cause all other threads (in the same process) also to go to sleep ? Do the behavior is same for detached threads also?
This is just a bug in the manual. wait suspends the calling thread, not the process. There is absolutely no way to suspend the whole process short of sending it SIGSTOP or manually suspending each thread one at a time.
As far as I know, calling wait from any thread will cause all threads which are associated with that process to halt.
But don't hold me to that. Best thing to do would be to test it.
Should only stop the current thread. If you want to make people ill when they look at your code and cause yourself a lot of problems you can use this for jury rigged thread synchronization. I wouldn't reccommend it though.
While running a thread program and repeatedly killing the main program using Ctrl + C, i see unexpected results in the program in second run. However, if i let the program run and voluntarily exit, there are no issues.
So, my doubt is, does Ctrl + C, kill threads also along with the main process?
Thanks in advance.
In multithreaded programming, signals are delivered to a single thread (usually chosen unpredictably among the threads that don't have that particular signal blocked). However, this does not mean that a signal whose default action is to kill the process only terminates one thread. In fact, there is no way to kill a single thread without killing the whole process.
As long as you leave SIGINT with its default action of terminating the process, it will do so as long as at least one thread leaves SIGINT unblocked. It doesn't matter which thread has it unblocked as long as at least one does, so library code creating threads behind the application's back should always block all signals before calling pthread_create and restore the signal mask in the calling thread afterwards.
Well, the only thing that Ctrl + C does is sending SIGINT to one thread in the process that is not masking the signal. Signals can be handled or ignored.
If the program does handle Ctrl+C, the usual behavior is self-termination, but once again, it could be used for anything else.
In your case, SIGINT is being received by one thread, which probably does kill itself, but does not kill the others.
Under Linux 2.6 using NPTL threads: I am assuming that the process uses the default signal handler, or calls exit() in it: Yes it does. The C library exit() call maps to the exit_group system call which exits all the threads immediately; the default signal handler calls this or something similar.
Under Linux 2.4 using Linuxthreads (or using 2.6 if your app still uses Linuxthreads for some weird reason): Not necessarily.
The Linuxthreads library implements threads using clone(), creating a new process which happens to share its address-space with the parent. This does not necessarily die when the parent dies. To fix this, there is a "master thread" which pthreads creates. This master thread does various things, one of them is to try to ensure that all the threads get killed when the process exits (for whatever reason).
It does not necessarily succeed
If it does succeed, it is not necessarily immediate, particularly if there are a large number of threads.
So if you're using Linuxthreads, possibly not.
The other threads might not exit immediately, or indeed at all.
However, no matter what thread library you use, forked child processes will continue (they might receive the signal if they are still in the same process-group, but can freely ignore it)
I use pthread_create(&thread1, &attrs, //... , //...); and need if some condition occured need to kill this thread how to kill this ?
First store the thread id
pthread_create(&thr, ...)
then later call
pthread_cancel(thr)
However, this not a recommended programming practice! It's better to use an inter-thread communication mechanism like semaphores or messages to communicate to the thread that it should stop execution.
Note that pthread_kill(...) does not actually terminate the receiving thread, but instead delivers a signal to it, and it depends on the signal and signal handlers what happens.
There are two approaches to this problem.
Use a signal: The thread installs a signal handler using sigaction() which sets a flag, and the thread periodically checks the flag to see whether it must terminate. When the thread must terminate, issue the signal to it using pthread_kill() and wait for its termination with pthread_join(). This approach requires pre-synchronization between the parent thread and the child thread, to guarantee that the child thread has already installed the signal handler before it is able to handle the termination signal;
Use a cancellation point: The thread terminates whenever a cancellation function is executed. When the thread must terminate, execute pthread_cancel() and wait for its termination with pthread_join(). This approach requires detailed usage of pthread_cleanup_push() and pthread_cleanup_pop() to avoid resource leakage. These last two calls might mess with the lexical scope of the code (since they may be macros yielding { and } tokens) and are very difficult to maintain properly.
(Note that if you have already detached the thread using pthread_detach(), you cannot join it again using pthread_join().)
Both approaches can be very tricky, but either might be specially useful in a given situation.
I agree with Antti, better practice would be to implement some checkpoint(s) where the thread checks if it should terminate. These checkpoints can be implemented in a number of ways e.g.: a shared variable with lock or an event that the thread checks if it is set (the thread can opt to wait zero time).
Take a look at the pthread_kill() function.
pthread_exit(0)
This will kill the thread.