I know that signal is a way of communication between CPU and OS kernel. A signal can interrupt the sequence of instructions, execute the handler and go back to the sequence of instructions.
Here is a piece of description of this link:
When a signal that is being caught is handled by a process, the normal
sequence of instructions being executed by the process is temporarily
interrupted by the signal handler. The process then continues
executing, but the instructions in the signal handler are now
executed. If the signal handler returns, the process continues
executing the normal sequence of instructions it was executing when
the signal was caught.
Here is my test:
void func(int p)
{
cout<<"int"<<endl;
sleep(5);
}
int main()
{
signal(SIGINT, func);
while(1)
{
cout<<"main"<<endl;
sleep(2);
}
return 0;
}
I execute it and if I press ctrl+C, int will be printed and then I have to wait for 5 seconds, no matter how many times ctrl+C I pressed while waiting for the 5 seconds, nothing happened.
Then I make another test:
void func(int p)
{
cout<<"int"<<endl;
sleep(5);
}
int main()
{
signal(SIGINT, func);
thread t1([](){while(1){cout<<"t1"<<endl; sleep(2);}});
thread t2([](){while(1){cout<<"t2"<<endl; sleep(2);}});
t1.join();
t2.join();
return 0;
}
For this code, I found that I could press ctrl+C three times continually and three int would be printed, then I have to wait for about 5 seconds.
So it seems that the first ctrl+C interrupts the t1 thread, the second interrupts the t2 thread and the third interrupts the main thread.
So signal only interrupt thread instead of the whole process if there are multi-threading?
INTRODUCTION
First of all each thread has its own mask that specifies which signals it is listening to. When a thread is created it inherits the mask of the thread that is creating it (let me call it the parent thread) that is active when pthread_create is called.
Generally it is better that if a thread is listening to a signal then the others should not, unless you want to have many threads that do the same stuff (for example when processing a connection request in a server to process many requests simultaneously). In this way you always know which thread is processing the signal. Otherwise you do not have any idea which thread is receiving the signal and which part of the program is executing: it becomes impossible to debug (an example is your own question).
To change the mask of the child thread that is being created from the parent thread you create a new mask, you set it active, create a new thread with pthread_create and then in the parent thread set the previous mask active again (see the code at the end of the answer).
EDIT: According to this post it is better to use sigaction() instead of signal. In modern systems signal() is implemented with sigaction() so there should not be any difference. However if its old implementation is used, problems might arise.
ANSWER
So signal only interrupt thread instead of the whole process if there
are multi-threading?
NO: Signals are just signals, they do not do anything. Actions associated to signals have the power to do stuff, including stopping the program or terminating the thread. Each signal has a default action associated and the default action for SIGINT is to interrupt the process.
With you handler you are overwriting the default action. So it will not stop the program anymore but it will do what you have specified in the thread function.
In the first case you have only one thread, the main one, which is an infinite loop, it always catches the signal as long as he is alive so that's why the behavior. If you resend the signal, the signal is momentarily blocked until the signal handler ends the execution. Nevertheless if many signals are sent while the handler is executing, you can loose some signals.
In fact as explained here, blocked signals are set to pending, but not queued. The term pending means that the operating system remembers that there is a signal waiting to be delivered at the next opportunity by setting a flag, and not queued means that it does this by setting a flag somewhere, but not by keeping an exact record of how many signals have arrived.
So if the signals is sent once, 5 times or more (try to press CTRL+C more times with your program: I have tried) while the signal handler is executing it produces the exactly same behaviour.
In your second case you have 3 threads: the main one, t1, and t2: all of them are enabled to see the signal SIGINT and all of them have associated the same signal handler. If you press 3 times one after the other all three of them will execute the handler: that is why you don't see any delay. If you press very very fast though and more than 3 times (the number of threads listening to that signal) I think you will see something similar to the first behaviour.
I will end my answer with the code I posted in a question where I was setting masks so that some signals were caught only by the main thread:
int main()
{
int err;
sigset_t omask, mask;
pthread_t thread_motionSensor;
pthread_t thread_tempReading;
pthread_t thread_platformPost;
printf("Created threads IDs\n");
...
if (signal(SIGINT, sig_handler)==SIG_ERR)
printf("Error on recording SIGINT HANDLER\n");
/*Create a new mask to block all signals for the following thread*/
sigfillset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, &omask);
printf("Trying to create threads\n");
if ((err = pthread_create (&thread_motionSensor, NULL, task1, NULL))!=0)
{
printf("Thread 1 not created: error %d\n", err);
err_exit((const char)err, "pthread_create error");
}
printf("Thread 1 created. Trying to create Thread 2\n");
if((err = pthread_create (&thread_tempReading, NULL, task2, NULL))!=0)
{
printf("Thread 2 not created: error %d\n", err);
err_exit((const char)err, "pthread_create error");
}
printf("Thread 2 created. Trying to create Thread 3\n");
if ((err = pthread_create (&thread_platformPost, NULL, task3, NULL))!=0)
{
printf("Thread 3 not created: error %d %d\n", err);
err_exit((const char)err, "pthread_create error");
}
printf("Thread 3 created\n");
/*The main thread must block the SIGALRM but catch SIGINT
SIGQUIT, SIGTERM, SIgkILL*/
/*empty the omask set from all signals */
sigemptyset(&omask);
/*add the signals to the omask*/
sigaddset(&omask, SIGINT);
sigaddset(&omask, SIGQUIT);
sigaddset(&omask, SIGKILL);
sigaddset(&omask, SIGTERM);
/*unblock all signals in omask*/
pthread_sigmask(SIG_UNBLOCK, &omask, NULL);
printf("Main thread waiting for signal\n");
/*pause will stop the main thread until any signal not blocked by omask will be received*/
pause();
printf("Exit signal received: cancelling threads\n");
pthread_cancel(thread_motionSensor);
pthread_cancel(thread_tempReading);
pthread_cancel(thread_platformPost);
pthread_join(thread_motionSensor, NULL);
pthread_join(thread_tempReading, NULL);
pthread_join(thread_platformPost, NULL);
printf("Exiting from main thread and process\n");
exit(0);
}
No matter how many threads the process has, some thread catches the signal and runs the signal handler while the other threads (if any) go on about their business. The signal is sent to the process, but what the process does when it gets the signal is dependent on how the process, and the threads in, configured its signal handlers.
The full rules are quite complicated and I think it's safe to say that very few programmers bother to full understand them and generally avoid signals except for very limited purposes. See here for more details.
So signal only interrupt thread instead of the whole process if there are multi-threading?
Yes. A signal interrupts a single thread of execution. At least according to the POSIX standard. C standard itself doesn't specify behaviour of processes or threads.
If a signal is generated for a multi threaded process as opposed to being generated for particular thread, the signal will be delivered to exactly one of the threads belonging to that process (unless the signal is blocked by all threads).
Related
In a system running Linux 2.6.35+ my program creates many child processes and monitors them. If a child process dies I do some clean-up and spawn the process again. I use signalfd() to get the SIGCHLD signal in my process. signalfd is used asynchronously using libevent.
When using signal handlers for non-real time signals, while the signal handler is running for a particular signal further occurrence of the same signal has to be blocked to avoid getting into recursive handlers. If multiple signals arrive at that time then kernel invokes the handler only once (when the signal is unblocked).
Is it the same behavior when using signalfd() as well? Since signalfd based handling doesn't have the typical problems associated with the asynchronous execution of the normal signal handlers I was thinking kernel can queue all the further occurrences of SIGCHLD?
Can anyone clarify the Linux behavior in this case ...
On Linux, multiple children terminating before you read a SIGCHLD with signalfd() will be compressed into a single SIGCHLD. This means that when you read the SIGCHLD signal, you have to clean up after all children that have terminated:
// Do this after you've read() a SIGCHLD from the signalfd file descriptor:
while (1) {
int status;
pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0) {
break;
}
// something happened with child 'pid', do something about it...
// Details are in 'status', see waitpid() manpage
}
I should note that I have in fact seen this signal compression when two child processed terminated at the same time. If I did only a single waitpid(), one of the children that terminated was not handled; and the above loop fixed it.
Corresponding documentation:
http://man7.org/linux/man-pages/man7/signal.7.html "By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued"
http://man7.org/linux/man-pages/man3/sigwait.3p.html "If prior to the call to sigwait() there are multiple pending instances of a single signal number, it is implementation-defined whether upon successful return there are any remaining pending signals for that signal number."
Actually the hassle-free way would be the waitfd functionally that would allow you to add a specific pid to poll()/epoll(). Unfortunately, it wasn't accepted to Linux years ago when it was proposed.
In Linux, when a signal is sent to a process/thread (for whatever reason), is the signal handler (assuming there is one, and the signal isn't blocked) called immediately?
I mean, I'm pretty sure that in the process/thread that handles the signal it will be called immediately, but I mean with respect to other processes/threads.
And if the handler is called immediately, will it also make the corresponding process/thread active (so that its normal execution continues immediatly)?
EDIT
As my original question seems to have been misunderstood, I'll try to explain again with an example.
Lets say in my computer I have a single CPU, and 2 processes running, process 'A' and process 'B'. And assume none of them is blocking in a system call (like sleep). Normally, I guess, the OS will switch between executing process 'A' and process 'B', after small periods of time (e.g. execute process 'A' for 100ms, then process 'B' for 100ms, then process A again for 100ms, etc.). Let's say process 'A' is now the active process (i.e. it's the one now occupying the CPU). Say now that process 'A' sends a signal to process 'B' (or, alternately, the OS sends this signal to process 'B', for whatever reason). Process 'B' has registered an handler for that signal, and is not blocking it. So the question is, will the OS now immediately stop executing process 'A' and switch to executing the signal handler of process 'B'? And if the answer is yes, will it afterwards immediately continue executing process 'B' (The normal code, not the signal handler), or switch back to executing process 'A', and only after some small period of time resume with executing process 'B'?
And then the same questions can be asked about threads rather than processes.
No, signals are delivered on context switch only. Upto that time all signals will be queued. Among many signals of same type, usually Only one signal is delivered to the destination. So i am comfortable to sat that more signals destroyed than delivered.
I suggest you to consult chapter regarding any unix book book. My favorite is understanding linux kernel and linux kernel development.
if you still need techincal help please comment about it
There are two cases: when the signaled process is active, and when it is blocked.
For the former case, according to http://www.tldp.org/LDP/tlk/ipc/ipc.html, the process would handle the signal when it exits from a system call. This would mean that a normal instruction like a = b+c (or its equivalent machine code) would not be interrupted because of signal. Signal handling may also be delayed in a CPU-intensive process.
However, when the process is blocked, it depends on whether the kernel function being called is interruptible (e.g., wait_event_interruptible). If it is interruptible, the process will wake up, otherwise, it will not until it leaves the uninterruptible function (due to IRQ, for instance).
Yes, the handler will be called immediately.
Suppose I have a process coded as below.
#include <stdio.h>
#include <signal.h>
void handle_signal(int signal);
volatile int i = 1;
int main( )
{
struct sigaction sa;
// Setup the sighub handler
sa.sa_handler = &handle_signal;
// Block every signal during the handler
sigfillset(&sa.sa_mask);
while(1)
{
if(i == 1)
{
printf("A");
}
}
return 0;
}
void handle_signal(int signal) {
/*
* Please note that printf et al. are NOT safe to use in signal handlers.
* Look for async safe functions.
*/
const char *signal_name;
sigset_t pending;
// Find out which signal we're handling
switch (signal) {
case SIGHUP:
signal_name = "SIGHUP";
break;
case SIGSTOP:
i = 0;
signal_name = "SIGSTOP";
break;
case SIGCONT:
signal_name = "SIGCONT";
i = 1;
break;
default:
fprintf(stderr, "Caught wrong signal: %d\n", signal);
return;
}
}
This prints A on shell all the time unless it receives SIGSTOP signal.
So, open the shell and do kill -STOP <pid of above process>
Verify that process is stopped, and then from the shell send the SIGCONT signal using kill -CONT <pid of above process>
And if the handler is called immediately, will it also make the corresponding process/thread active (so that its normal execution continues immediatly)
Your signal handler has its own context. So there is no thread which must be activated for handling your signal. But there are some issues which must be kept in mind. If your thread is waiting with some syscalls like sleep or read/write or any other blocking operation, this system call will be interrupted and the return value from that call give you the information, that your process ( not thread! ) has received a signal.This return value is EINTR. If your thread is simply running or sleeping without waiting on a system call, nothing else is happened! Simply the handler is invoked without any changes in scheduling your threads inside your process.
I have written a C/C++ code which implements socket connection and the main thread is in continuous loop listening at its port. When a connection request comes at this port, I have spawned a thread using pthread calls and offloaded the work on this thread. As such i have 'n' threads getting created dynamically for 'n' incoming requests.
The problem is that, if one thread terminates the main thread also terminates.
I have used pthread_join() but It waits for the thread in the argument to finish.In my case, the new threads are not getting spawned once the call to pthread_join() is made.
pthread_t t;
while(1) //server always to be in listen mode
{
client_len=sizeof(client_sockaddr);
client_sockfd=accept(server_sockfd,(struct sockaddr*)&client_sockaddr,&client_len);
pthread_create(&t,NULL,server_thread,(void*)client_sockfd);
(void)pthread_join(t,NULL);
}
If you don't care about the return value from your threads, and you're not interested in when they complete, then you should detach them with pthread_detach or simply create them in a detached state to begin with:
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
while(1) //server always to be in listen mode
{
client_len=sizeof(client_sockaddr);
client_sockfd=accept(server_sockfd,(struct sockaddr*)&client_sockaddr,&client_len);
pthread_t t;
pthread_create(&t,&thread_attr,server_thread,(void*)client_sockfd);
}
pthread_attr_destroy(&thread_attr);
Add printf("check string\n"); after pthread_join in your code. compile and run it now. You might get some idea about your problem.
You will not meet printf function.
Reason for the behavior is pthread_join will wait for first created thread to finish the job.
so unless and until first thread finish the job new thread will not created. So your code will not accept any new client connection.
So don't use pthred_join inside your while(1) then your problem will be solved.
pthread_join is mostly useful when main process want to wait until thread finishes the job.
In my program, it start a boost thread and keep the handler as a member of the main thread.
When user press the cancel button I need to check the started thread still running and if it is running need tho kill that specific thread. here is the pseudo code.
cheating thread
int i =1;
boost::thread m_uploadThread = boost::thread(uploadFileThread,i);
This is the method use to check if thread is still running, but it is not working
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(2);
if (this->uploadThread.timed_join(timeout)){
//Here it should kill the thread
}
The return value true means the thread is completed before the call times out. And looks like what you want is
if(!this->uploadThread.timed_join(timeout))
For stop your thread you can use:
my_thread.interrupt();
in order this to work you have to set an interruption point at the point you want the thread's function stops when you interrupt.
Note: the interruption by it self don't stop the thread it just set a flag and the when an interruption point is reached the thread is interrupted. If no interruption point is found, the thread don't stop.
You can also handle the interrupted exception boost::thread_interrupted that way you can do things depending on if the thread was interrupted or not.
For instance lets assume the next code is inside a thread function:
try
{
//... some important code here
boost::this_thread.interruption_poit(); // Setting interrutption point.
}
catch(boost::thread_interrupted&)
{
// Now you do what ever you want to do when
// the thread is interrupted.
}
I have an application which starts 5 threads.
After starting those threads nothing happens in main().
main(){
`start thread 1..5
}
How do I loop infinitely in main() so my program will run continuously until it gets a signal.
I don't want to use
while(true)
because it will eat CPU cycle. (As I think )
Edit:
I am using gcc 4
Thread Api :pthread
OS : Linux
the simplest would be:
while (true) sleep(1000);
and the best would be to join() all the five threads.
The sigsuspend() function is designed for precisely this purpose - it will suspend the calling thread until it recieves a signal that results in the calling of a signal handler.
To avoid a race condition (where the signal arrives just before your process calls sigsuspend()), you should block the signal, check for it, then pass a mask to sigsuspend() that unblocks it:
/* Block SIGUSR1 */
sigset_t sigusr1set, origset;
sigemptyset(&sigusr1set);
sigaddset(&sigusr1set, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigusr1set, &origset);
/* Set up threads etc here */
/* Unblock SIGUSR1 and wait */
sigdelset(&origset, SIGUSR1);
sigsuspend(&origset);
Join those threads see pthread_join.
You could try the Boost::Synchronization functions, like this:
main(){
`start thread 1..5
wait for signal
exit
}
Windows? Use WaitForMultipleObjects.