Create signal handler for a single thread - c

I'm wondering if sigaction will create a signal handler for the calling thread or the whole process. If it unblocks a signal and creates a signal handler for the entire process, then how can I make sure only a single thread will use the signal handler and have other threads block the signal.
In my case, I want a single thread to call a signal handler when an alarm signal goes off and the other threads to simply block it.
void alarmSigHandler(int signo){
}
void* alarm_thread_start_routine(void *arg){
// Perform some tasks
}
int main(){
// Main thread start
/* Unblock alarm signal */
/* Assign signal handler for alarm signal */
/* Launch alarm signal handler thread */
/* Block alarm signal with pthread_sigmask */
/* Do something */
return 0;
}
http://vip.cs.utsa.edu/classes/cs3733f2013/notes/SignalsAndThreads.html
If a signal is sent to a threaded program, any of the threads can handle the signal.
Each thread inherits the process signal mask, but each thread has its own signal mask that can be modified with pthread_sigmask.
sigprocmask should not be used in a threaded environment, but it can be used before the threads are created.
The simplest way to handle signals in a multithreaded environment is to have a thread dedicated to signal handling.
Issues involving signal safety can be handled by using sigwait:
The main process blocks all signals before creating any threads.
No signal handlers are set up.
A thread is created to handle the signals.
That thread sets up a sigset_t containing the signals of interest.
It loops, calling sigwait and handles the pending signals.

You say:
In my case, I want a single thread to call a signal handler when an alarm signal goes off and the other threads to simply block it.
Try this:
void *alrm_thread(void *arg) {
// install SIGALRM handler
// unblock SIGALRM
... do stuff ...
}
int main(int argc, char **argv) {
// block SIGALRM
// spawn alarm_thread
... do stuff or spawn other threads ..
}
SIGALRM will only be delivered to the "alrm_thread" above.
UPDATE
(Adapting Alex Che's apt comments)
This works because each thread has its own signal mask inherited from the thread which creates it.
Masking (blocking) SIGALRM in main() right away ensures all subsequent threads begin life with SIGALRM blocked. Our special thread installs the handler and unblocks SIGALRM. Since this special thread is the only thread able to receive an ALRM, it will be the thread that runs the handler.
(Now, there are some signal nuances just around the corner. Handlers or signal dispositions are process-global attributes shared by all threads. Signals can be process-directed or thread-directed. However, for your case, which is a very common case, the above is suitable.)

From the man page for signals:
The signal disposition is a per-process attribute: in a multithreaded
application, the disposition of a particular signal is the same for
all threads.
So yes, when you set a signal handler it will handle signals sent to the process; signals aren't sent to each thread individually, it is sent to any one of the threads that aren't blocking the specific message being sent.

Related

C Signal usage and process using IPC message queues

I have a program that uses a signal (SIGUSR2) for setup a catch handler function to process high priority incoming messages.
The program receives incoming messages off an IPC message queue using msgrcv() in its main loop. When the sender of messages to the IPC message queue wants to notify the program that a high priority one is incoming, it sends SIGUSR2 to the process to have it stop processing any current message that may be being processed.
In the signal catch handler function I first upon entry do:
signal(SIGUSR2, SIG_IGN);
to ignore any new signals for preemption to occur.
then the code processes the preemption request where it stores the currently being processed message back into the queue, housekeeping, etc. and then just before returning from the signal handler function it does:
signal(SIGUSR2, sighandler_func);
Question: If another flash processing signal is received just a nanosecond after
the above signal call is issued, will the process re-dispatch to the
signal handler function again? ie: if the code in the main loop where
it does the sighold(SIGUSR2) and sigrelse(SIGUSR2) to stop / start the
receipt of the preemption signal take precedence or is it just the
above signal call that re-energizes the signal handler?
You should use sigaction for that:
struct sigaction act;
memset(&act, 0, sizeof(act);
act.sa_handler = sighandler_func;
sigaction(SIGUSR2, &act, NULL);
This way, the signal handler is automatically called with the signal blocked, which caused the event (in your case SIGUSR2). If now a SIGUSR2 arrives during the execution of the handler, it is blocked until the signal handler returns. Then, (when the signal is unblocked), the signal handler is called immediately again.
However, you will have to handle the case, that multiple SIGUSR2 arrive during one execution of the signal handler properly, since it will be called only once after return of the handler then.

What is sigaddset used for?

I have this code where I use sigaddset and sigaction. However if I comment segaddset the result is the same
struct sigaction act;
act.sa_handler = process_alarm;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask, SIGINT);
sigaction(SIGALRM, &act, NULL);
for(;;)
{
alarm(3);
pause();
}
Why do I need to use it?
You are doing 2 things here:
Populating a sigset_t. A sigset_t is just a collection of values for signals, and are used in various system calls. You can:
Create an empty sigset_t (sigemptyset()
Add a signal to the set (sigaddset())
Remove a signal to the set (sigdelset())
etc...
Setting the signal mask for the signal handler. You do that by manipulating the sigset_t sa_mask member of the struct sigaction when you set up a signal handler in with a call to sigaction().
The signal mask of a signal handler means that while the signal handler is executing, the signals that are in the mask will be blocked - i.e. those signals will not be handled as long as they are blocked. When the signal handler are finished, the signals in will be unblocked.
A signal that is blocked isn't "lost", it will be handled when that particular signal is unblocked again.
The sigaddset(&act.sa_mask, SIGINT); means the the SIGINT signal cannot occur while the code for the SIGALRM handler is running.
On the other hand, if you comment out sigaddset(&act.sa_mask, SIGINT);, you're left with just an empty list of signals created with sigemptyset(&act.sa_mask);. So any signals that occur while the SIGALRM handler function is running might preempt that handler and execute the signal handler for that other signal.
For a SIGINT, you would normally not notice any difference with manual testing - it's unlikely you manage to hit CTRL-C exactly when your handler for SIGALRM is running, and your SIGALRM handler probably runs quickly enough that you would not notice if the SIGINT was slightly delayed.
Signals sets are manipulated via sigset_t type. Several operations are available for signals sets:
create an empty set S via sigemptyset, S=∅
add a signal s to a set S via sigaddset, S=S∪{s}
remove a signal s from a set via sigdelset, S=S\{s}
create the set of all possible signals via sigfillset.
test is a signal s is in a given set S via sigismember, s∈S?
Such a set is used at different places: setting a new process signal mask, blocking set during signal handling, requesting the set of pending signals, etc.
If you want to catch different signals, it may appears that some catching functions must not be interrupted with others, so you can add a set of signals to be blocked during the delivery of a given signal. You actually decided (when uncommented) to block SIGINT during SIGALRM delivery. So you can only observe this by sending a SIGINT during the execution of the handler; which is difficult to realize.
A example where it can be important ?
Suppose that the handler of SIGUSR1 modify a given data structure and that the handler for SIGUSR2 uses that same data structure. It is very important to make both handlers not concurrent, one can be run after the other but you probably don't want to be interrupted by one during the delivery of the other. Your code is self-concurrent, say that even in the case of only one thread, signals can lead you to concurrency.
sigaddset is used for adding the corresponding signal mask to that sigset_t variable.
In sigaction, it is not required. You can use that when you are using the sigprocmask which is for blocking the signal which we mentioning in that variable.

Block signals for complete process in a multithreaded environment

I have a 'C' application in linux where in i have register SIGALRM handler. My SIGALRM handler updates some global data that other threads are also accessing.
Requirement:
In order to protect the global data, i need to block the signal completely while i am accessing it inside the thread. So i need a way to implement it.
Problem:
I am not able to block the signals completely.
sigprocmask is not working. Although it blocks signal if main is the only thread running. But when multiple threads are running SIGALRM keeps on coming.
I have tested pthread_sigmask but that updates the signal mask for current thread only.
Adding code logic:
sig_atomic_t atm_var;
void signal_handler()
{
atm_var++;
}
void thread_func()
{
pthread_sigmask(UNBLOCK,...);
while(1)
{
/* some stuff */
pthread_sigmask(BLOCK,...);
/* critical section, can easily access or modify atm_var */
pthread_sigmask(UNBLOCK,...);
}
}
int main()
{
sigprocmask(BLOCK,...);
pthread_create(...,thread_func,...);
sigaction(SIGALRM,...);
setitimer(ITIMER_REAL,...);
while(1)
{
}
}
Adding one more point: How safe it is to modify a sig_atomic_t variable (that signal handler is modifying) in main or other threads?
OR
Will it be safe practice to not to block signal while i modify the sig_atomic_t variable inside main or other threads?
Your problem is that various signals can be directed at the whole process or a particular thread. When directed at the whole process then they will be delivered to any thread that doesn't have them blocked.
man (7) signal
A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal.
Because the signal masks are inherited by each thread from whatever thread created them, a fairly standard technique is to block them in the creator (for simplicity let's say that is main) and then let each spawned thread unblock signals as appropriate.
A common variation on this is to block them in main, and keep them blocked in all spawned threads except one. That one thread unblocks the signals and all process directed signals get aimed at it to handle.
The above is probably what you want to do. You probably are properly blocking SIGALRM in the thread which is running the signal handler. Unfortunately that isn't going to prevent SIGALRM from being delivered to a second thread.

How to wait a signal in a thread?

I'm sending a signal from a module in the kernel space to a process. This process has one thread waiting for the signal.
I read the signal manual and it says:
The signal disposition is a per-process attribute: in a multithreaded application, including the disposition of a signal is the same for all threads.
Thus, and according to the manual pthread_sigmask:
http://man7.org/linux/man-pages/man3/pthread_sigmask.3.html
I'm trying to block the signal in the main function of the application by calling:
siginfo_t infoh1;
sigset_t waith1;
sigemptyset(&waith1);
sigaddset(&waith1, SIG_HILO1);
pthread_sigmask( SIG_BLOCK, &waith1, NULL );
Note that the thread is waiting for it in its execution function.
result = sigwaitinfo (&waith1, &infoh1);
The signal is sent, but the thread never receives it (it hangs waiting).
What am I doing wrong? I tested with different codes from different websites without success.
I use signals a lot in my *nix code and I don't think this is a good approach.
I recommend that all threads are set to ignore signals. The main process handles the signal while the thread sits on a mutex/condition. On signal the main process sets a global static flag with the signal type and then notifies the thread which duly checks the flag to see which signal was caught.
It's a safe and easy solution.

POSIX Threads and signal masks

Is there a way to change the signal mask of a thread from another thread?
I am supposed to write a multithreaded C application that doesn't use mutex, semaphores and condition variables, only signals.
So it would look like something like this:
The main Thread sends SIGUSR1 to its process and and one of the 2 threads (not including the main thread), will respond to the signal and block SIGUSR1 from the sigmask and sleep. Then the main thread sends SIGUSR1 again, the other thread will respond, block SIGUSR1 from its sigmask, unblock SIGUSR1 from the other threads sigmask, so it will respond to SIGUSR1 again.
So essentially whenever the main thread sends SIGUSR1 the two other threads swap between each other.
Can somebody help?
You are probably looking for pthread_sigqueue(3) called from the main thread, and sigwait(3) or sigtimedwait(2) in the child thread(s).
A thread can only modify its own signal mask (via pthread_sigmask()). If you want to modify another thread's signal mask, you will have to write code yourself to ask the other thread to do it.
Signals are being sent to the process here, so kill() or sigqueue() are the functions to use. The latter will avoid coalescing multiple signals together which may happen with kill().

Resources