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.
有帮助吗?

解决方案 2

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.

其他提示

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.)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top