In my C program, I want to get the PID of the process, send a SIGSTOP to that and wait until a SIGCONT arrives from another terminal. So, the procedure looks like
int pid_t = getpid();
printf("PID %d has been stopped\n", pid_t);
STOP(pid_t);
while (not_received_CONT(pid_t))
;
// continue the program
How can I complete that?
What you're writing doesn't make sense. When you stop the process, there is no more instructions being processed in the program and as such there is no while loop to wait for receiving the continuation.
If you check man 7 signal you can see that only one signal currently (in Linux) causes continuation of a process: SIGCONT, hence its not technically necessary to process a while loop check if you didn't get a continuation -- UNLESS you've got a situation where a number of signals are pending and you're trying to determine that.
You can rewrite your code implicitly to be:
int pid = getpid();
printf("PID %d has been stopped\n", pid);
kill(pid, SIGSTOP);
/* Process implicitly continues here, no while needed */
There are multiple vectors in Linux to manage signal handling which may not necessarily be portable.
There is the traditional signal/sigaction method of catching signals and invoking function calls on receipt of the signal. This can come with some unexpected caveats if you aren't careful.
Another way you can manage signals is the use of sigwait, you block the signal with sigprocmask and can consume signals in a safe fashion using sigwait to consume the signal at some controlled point in your process.
Finally you can do similar to sigwait with a signalfd. The main difference between it and sigwait being you can poll the FD to determine its readiness (a signal is received) then read the FD to consume the signals. This makes it a very nice way to manage signals in event driven programs.
Fellow coders.
If I send a SIGINT signal to a thread stuck on pthread_cond_wait(), when sign_handler() returns, will pthread_cond_wait() return as well?
If not, is there any way to make pthread_cond_wait() return?
If I send a SIGINT signal to a thread stuck on pthread_cond_wait(), when sign_handler() returns, will pthread_cond_wait() return as well?
No.
If not, is there any way to make pthread_cond_wait() return?
No, you're trying to use the wrong tool to solve whatever underlying problem you have.
(Technically, pthread_cond_timedwait() is allowed to return when interrupted by a signal delivery, but it does not do so, at least when using GNU glibc 2.27 on x86-64 running kernel 5.3.0. Yes, I checked.)
How can I fix my problem?
Let's assume that a condition variable is the best option for your use case. (That's just a guess, though; you didn't tell us about your real problem you're trying to solve, only how your chosen solution isn't working.)
Then, the recommended solution is to use a helper thread to catch signals like SIGINT, using sigwaitinfo() or sigtimedwait(). That helper thread can then set a specific volatile sig_atomic_t you_need_to_exit flag, and pthread_cond_signal() or pthread_cond_broadcast() on the relevant condition variables to let them know something important happened. Those waiting on the condition variables should obviously first check the helper flag; and if set, assume that that was the source for the wakeup signal. Usually I name such flags need_to_exit or similar.
The key in such signal handling helper threads is that the signals need to be blocked in all threads (including the handling helper thread itself). It is best to do this in the main thread before creating any other threads, as then the created threads inherit that same signal mask.
The siginfo_t structure contains all kinds of useful information. Most useful is perhaps the .si_pid field, which tells which process (or 0 if kernel) sent the signal. That way, if you use say SIGRTMIN+0 to SIGRTMAX-0 signals for internal purposes, you can ignore them unless they come from the process itself (other threads, .si_pid == getpid()).
Thread cancellation (deferred, at cancellation points; pthread_cond_wait() being a cancellation point) is another option. You can use pthread_cleanup_push() to set/add functions to be run if the thread is cancelled. This basically forcibly kills the target thread, but it can run any cleanup functions it has set up before it dies. You can also defuse any cleanup functions using pthread_cleanup_pop() -- a parameter specifies whether the cleanup function is run and discarded, or just discarded. But, when cancelled, the thread always dies.
Do use pthread_attr_t to limit the stack size to a sane power of two. If you don't have any large arrays or structures on stack (local variables), then something like
#include <limits.h>
#ifndef THREAD_STACK_SIZE
#define THREAD_STACK_SIZE (4 * PTHREAD_STACK_MIN)
#endif
with
sigset_t mask;
pthread_attr_t attrs;
int err;
/* Block SIGINT in this (and all created threads) */
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
err = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (err) {
fprintf(stderr, "Cannot block signals: %s.\n", strerror(err));
return EXIT_FAILURE;
}
/* Create stack size attribute. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
/*
* Create threads, use &attrs for the second parameter.
*/
/* Optional cleanup - it's a good idea to be careful. */
pthread_attr_destroy(&attrs);
should work fine, for both stack size and blocking some signals in all threads (by blocking them first in the thread that creates the other threads; they'll inherit the signal mask).
You can add any other signals to the blocked mask you like, except that SIGKILL and SIGSTOP cannot be blocked, caught, or ignored.
The pthread_attr_t second parameter to pthread_create() is just a collection of settings (or attributes), like configuration; they are not "consumed" by the pthread_create() call. You can use the same set of attributes any number of times. This one contains only the desired stack size. (It does not contain the stack itself, only the desired size.)
The default stack size is very large, typically 8 MiB, which means that a lot of virtual memory is reserved for thread stacks for no good reason, really. Also, it severely limits the number of threads a process can create.
In many ways, having a helper thread for signal handling is easier than actual signal handlers, because only async-signal safe functions are safe to use in a signal handler; whereas in the helper thread, you can use all.
Currently I am trying to create a signal handler that, when it receives a SIGTERM signal, it closes open network sockets and file descriptors.
Here is my SigHandler function
static void SigHandler(int signo){
if(signo == SIGTERM){
log_trace("SIGTERM received - handling signal");
CloseSockets();
log_trace("SIGTERM received - All sockets closed");
if (closeFile() == -1)
log_trace("SIGTERM received - No File associated with XXX open - continuing with shutdown");
else
log_trace("SIGTERM received - Closed File Descriptor for XXX - continuing with shutdown");
log_trace("Gracefully shutting down XXX Service");
} else {
log_trace("%d received - incompatible signal");
return;
}
exit(0);
}
This code below sits in main
if (sigemptyset(&set) == SIGEMPTYSET_ERROR){
log_error("Signal handling initialization failed");
}
else {
if(sigaddset(&set, SIGTERM) == SIGADDSET_ERROR) {
log_error("Signal SIGTERM not valid");
}
action.sa_flags = 0;
action.sa_mask = set;
action.sa_handler = &SigHandler;
if (sigaction(SIGTERM, &action, NULL) == SIGACTION_ERROR) {
log_error("SIGTERM handler initialization error");
}
}
When I send kill -15 PID, nothing happens. The process doesn't terminate, nor does it become a zombie process (not that it should anyway). I do see the traces printing within the SigHandler function however, so I know it is reaching that point in the code. It just seems that when it comes to exit(0), that doesn't work.
When I send SIGKILL (kill -9 PID) it kills the process just fine.
Apologies if this is vague, I'm still quite new to C and UNIX etc so I'm quite unfamiliar with most of how this works at a low level.
Your signal handler routine is conceptually wrong (it does not use just async-signal-safe functions). Read carefully signal(7) and signal-safety(7) to understand why. And your handler could apparently work most of the time but still be undefined behavior.
The usual trick is to set (in your signal handler) some volatile sig_atomic_t variable and test that variable outside of the signal handler.
Another possible trick is the pipe(7) to self trick (the Qt documentation explains it well), with your signal handler just doing a write(2) (which is async-signal-safe) to some global file descriptor obtained by e.g. pipe(2) (or perhaps the Linux specific eventfd(2)...) at program initialization before installing that signal handler.
A Linux specific way is to use signalfd(2) for SIGTERM and handle that in your own event loop (based upon poll(2)). That trick is conceptually a variant of the pipe to self one. But signalfd has some shortcomings, that a web search will find you easily.
Signals are conceptually hard to use (some view them as a design mistake in Unix), especially in multi-threaded programs.
You might want to read the old ALP book. It has some good explanations related to your issue.
PS. If your system is QNX you should read its documentation.
You should be using _exit from the signal handler instead, this also closes all the files.
Also read (very carefully) Basile's answer and take a long hard look at the list of async safe functions which you are allowed to use in signal handlers.
His advice about just changing a flag and testing it in your code is the best way if you need to do something you aren't allowed in the signal handler. Note that all blocking posix calls can be interrupted by signals so testing your atomic variable if you get an error on a blocking call (to say read) is a sure way to know if you have received a signal.
I am building my own shell in C. I want to implement an builtin called alarm that takes in an integer argument for the number of seconds. The builtin just sends the user a message after i seconds (once) but the shell functionality should continue working in the meantime.
Heres what I have so far:
int seconds;
int main(int argc, char const *argv[], char* envp[]){
...
signal(SIGALRM, alarmHandler);
...
}
void alarmHandler(int sig) {
signal(sig, SIG_IGN);
alarm(seconds);
printf("%s\n", "message");
signal(SIGALRM, alarmHandler);
}
void mainProgram(char* string, char* argument){
... //built ins that don't require forking
pid_t processID = fork();
if(processID==0){ //child
if(strcmp(string, "alarm") == 0){
seconds = atoi(argument);
signal(SIGALRM, alarmHandler);
}else{ // parent
usleep(100000)
}
Clearly that doesn't work. I'm kinda lost. I've been trying this for the past couple of hours and I'm unsure of what to do.
Perhaps you've got the wrong idea of what signal does...
The signal system call can be used for setting up handling of signals. Generally speaking, use the kill system call for sending signals.
OTOH, perhaps it's the difference between BSD signal handling semantics and System V signal handling semantics that's contributing to the confusion. System V signal handling semantics can necessitate calling signal (again) within the signal handler function. Newer linux systems at least stick with the BSD signal handling semantics which are reliable and don't require signal to be called again unless you wanted to change the handler that gets invoked.
As a side note, once you get past using signal correctly, I'd recommend using sigaction instead. You can read the 'Portability' section of the signal manual page that I linked to learn more about why you should use sigaction instead of signal.
But onwards...
There are other system calls that can be used to send signals in addition to the kill system call. Like in your case you may want to use alarm or setitimer.
Alternatively, if you wanted to implement something like what alarm does (without using alarm or setitimer), you could use a separate process (via a call to fork perhaps) that calls a sleep function followed by calling kill like this:
usleep(100000);
kill(pid, SIGALRM);
In this example then, pid would be the process ID of the process that you wanted to send the SIGALRM signal to (which is the signal that alarm sends).
Hope this helps answer your question.
I have a thread running in the background that is reading events from an input device in a blocking fashion, now when I exit the application I want to clean up the thread properly, but I can't just run a pthread_join() because the thread would never exit due to the blocking IO.
How do I properly solve that situation? Should I send a pthread_kill(theard, SIGIO) or a pthread_kill(theard, SIGALRM) to break the block? Is either of that even the right signal? Or is there another way to solve this situation and let that child thread exit the blocking read?
Currently a bit puzzled since none of my googling turned up a solution.
This is on Linux and using pthreads.
Edit: I played around a bit with SIGIO and SIGALRM, when I don't install a signal handler they break the blocking IO up, but give a message on the console ("I/O possible") but when I install a signal handler, to avoid that message, they no longer break the blocking IO, so the thread doesn't terminate. So I am kind of back to step one.
The canonical way to do this is with pthread_cancel, where the thread has done pthread_cleanup_push/pop to provide cleanup for any resources it is using.
Unfortunately this can NOT be used in C++ code, ever. Any C++ std lib code, or ANY try {} catch() on the calling stack at the time of pthread_cancel will potentially segvi killing your whole process.
The only workaround is to handle SIGUSR1, setting a stop flag, pthread_kill(SIGUSR1), then anywhere the thread is blocked on I/O, if you get EINTR check the stop flag before retrying the I/O. In practice, this does not always succeed on Linux, don't know why.
But in any case it's useless to talk about if you have to call any 3rd party lib, because they will most likely have a tight loop that simply restarts I/O on EINTR. Reverse engineering their file descriptor to close it won't cut it either—they could be waiting on a semaphore or other resource. In this case, it is simply impossible to write working code, period. Yes, this is utterly brain-damaged. Talk to the guys who designed C++ exceptions and pthread_cancel. Supposedly this may be fixed in some future version of C++. Good luck with that.
I too would recommend using a select or some other non-signal-based means of terminating your thread. One of the reasons we have threads is to try and get away from signal madness. That said...
Generally one uses pthread_kill() with SIGUSR1 or SIGUSR2 to send a signal to the thread. The other suggested signals--SIGTERM, SIGINT, SIGKILL--have process-wide semantics that you may not be interested in.
As for the behavior when you sent the signal, my guess is that it has to do with how you handled the signal. If you have no handler installed, the default action of that signal are applied, but in the context of the thread that received the signal. So SIGALRM, for instance, would be "handled" by your thread, but the handling would consist of terminating the process--probably not the desired behavior.
Receipt of a signal by the thread will generally break it out of a read with EINTR, unless it is truly in that uninterruptible state as mentioned in an earlier answer. But I think it's not, or your experiments with SIGALRM and SIGIO would not have terminated the process.
Is your read perhaps in some sort of a loop? If the read terminates with -1 return, then break out of that loop and exit the thread.
You can play with this very sloppy code I put together to test out my assumptions--I am a couple of timezones away from my POSIX books at the moment...
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
int global_gotsig = 0;
void *gotsig(int sig, siginfo_t *info, void *ucontext)
{
global_gotsig++;
return NULL;
}
void *reader(void *arg)
{
char buf[32];
int i;
int hdlsig = (int)arg;
struct sigaction sa;
sa.sa_handler = NULL;
sa.sa_sigaction = gotsig;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
if (sigaction(hdlsig, &sa, NULL) < 0) {
perror("sigaction");
return (void *)-1;
}
i = read(fileno(stdin), buf, 32);
if (i < 0) {
perror("read");
} else {
printf("Read %d bytes\n", i);
}
return (void *)i;
}
main(int argc, char **argv)
{
pthread_t tid1;
void *ret;
int i;
int sig = SIGUSR1;
if (argc == 2) sig = atoi(argv[1]);
printf("Using sig %d\n", sig);
if (pthread_create(&tid1, NULL, reader, (void *)sig)) {
perror("pthread_create");
exit(1);
}
sleep(5);
printf("killing thread\n");
pthread_kill(tid1, sig);
i = pthread_join(tid1, &ret);
if (i < 0)
perror("pthread_join");
else
printf("thread returned %ld\n", (long)ret);
printf("Got sig? %d\n", global_gotsig);
}
Your select() could have a timeout, even if it is infrequent, in order to exit the thread gracefully on a certain condition. I know, polling sucks...
Another alternative is to have a pipe for each child and add that to the list of file descriptors being watched by the thread. Send a byte to the pipe from the parent when you want that child to exit. No polling at the cost of a pipe per thread.
Old question which could very well get a new answer as things have evolved and a new technology is now available to better handle signals in threads.
Since Linux kernel 2.6.22, the system offers a new function called signalfd() which can be used to open a file descriptor for a given set of Unix signals (outside of those that outright kill a process.)
// defined a set of signals
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
// ... you can add more than one ...
// prevent the default signal behavior (very important)
sigprocmask(SIG_BLOCK, &set, nullptr);
// open a file descriptor using that set of Unix signals
f_socket = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC);
Now you can use the poll() or select() functions to listen to the signal along the more usual file descriptor (socket, file on disk, etc.) you were listening on.
The NONBLOCK is important if you want a loop that can check signals and other file descriptors over and over again (i.e. it is also important on your other file descriptor).
I have such an implementation that works with (1) timers, (2) sockets, (3) pipes, (4) Unix signals, (5) regular files. Actually, really any file descriptor plus timers.
https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/snap_communicator.cpp
https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/snap_communicator.h
You may also be interested by libraries such as libevent
Depends how it's waiting for IO.
If the thread is in the "Uninterruptible IO" state (shown as "D" in top), then there really is absolutely nothing you can do about it. Threads normally only enter this state briefly, doing something such as waiting for a page to be swapped in (or demand-loaded, e.g. from mmap'd file or shared library etc), however a failure (particularly of a NFS server) could cause it to stay in that state for longer.
There is genuinely no way of escaping from this "D" state. The thread will not respond to signals (you can send them, but they will be queued).
If it's a normal IO function such as read(), write() or a waiting function like select() or poll(), signals would be delivered normally.
One solution that occurred to me the last time I had an issue like this was to create a file (eg. a pipe) that existed only for the purpose of waking up blocking threads.
The idea would be to create a file from the main loop (or 1 per thread, as timeout suggests - this would give you finer control over which threads are woken). All of the threads that are blocking on file I/O would do a select(), using the file(s) that they are trying to operate on, as well as the file created by the main loop (as a member of the read file descriptor set). This should make all of the select() calls return.
Code to handle this "event" from the main loop would need to be added to each of the threads.
If the main loop needed to wake up all of the threads it could either write to the file or close it.
I can't say for sure if this works, as a restructure meant that the need to try it vanished.
I think, as you said, the only way would be to send a signal then catch and deal with it appropriately. Alternatives might be SIGTERM, SIGUSR1, SIGQUIT, SIGHUP, SIGINT, etc.
You could also use select() on your input descriptor so that you only read when it is ready. You could use select() with a timeout of, say, one second and then check if that thread should finish.
I always add a "kill" function related to the thread function which I run before join that ensures the thread will be joinable within reasonable time. When a thread uses blocking IO I try to utilize the system to break the lock. For example, when using a socket I would have kill call shutdown(2) or close(2) on it which would cause the network stack to terminate it cleanly.
Linux' socket implementation is thread safe.
I'm surprised that nobody has suggested pthread_cancel. I recently wrote a multi-threaded I/O program and calling cancel() and the join() afterwards worked just great.
I had originally tried the pthread_kill() but ended up just terminating the entire program with the signals I tested with.
If you're blocking in a third-party library that loops on EINTR, you might want to consider a combination of using pthread_kill with a signal (USR1 etc) calling an empty function (not SIG_IGN) with actually closing/replacing the file descriptor in question. By using dup2 to replace the fd with /dev/null or similar, you'll cause the third-party library to get an end-of-file result when it retries the read.
Note that by dup()ing the original socket first, you can avoid needing to actually close the socket.
Signals and thread is a subtle problem on Linux according to the different man pages.
Do you use LinuxThreads, or NPTL (if you are on Linux) ?
I am not sure of this, but I think the signal handler affects the whole process, so either you terminate your whole process or everything continue.
You should use timed select or poll, and set a global flag to terminate your thread.
I think the cleanest approach would have the thread using conditional variables in a loop for continuing.
When an i/o event is fired, the conditional should be signaled.
The main thread could just signal the condition while chaning the loop predicate to false.
something like:
while (!_finished)
{
pthread_cond_wait(&cond);
handleio();
}
cleanup();
Remember with conditional variables to properly handle signals. They can have things such as 'spurious wakeups'. So i would wrap your own function around the cond_wait function.
struct pollfd pfd;
pfd.fd = socket;
pfd.events = POLLIN | POLLHUP | POLLERR;
pthread_lock(&lock);
while(thread_alive)
{
int ret = poll(&pfd, 1, 100);
if(ret == 1)
{
//handle IO
}
else
{
pthread_cond_timedwait(&lock, &cond, 100);
}
}
pthread_unlock(&lock);
thread_alive is a thread specific variable that can be used in combination with the signal to kill the thread.
as for the handle IO section you need to make sure that you used open with the O_NOBLOCK option, or if its a socket there is a similar flag you can set MSG_NOWAIT??. for other fds im not sure