The use of signaling mechanisms in multi-threaded Linux is fundamentally different from the use of signaling mechanisms in the process. In the process environment, the signal processing is to register the signal processing function, when the signal occurs asynchronously, call the processing function to process the signal. It is completely asynchronous (we have no idea that the signal will arrive at the execution point of the process!) )。 However, the implementation of signal processing function has many limitations, such as some functions cannot be called in the signal processing function, such as some functions read, recv and other calls will be asynchronous signal to interrupt (interrupt), So we have to deal with situations where these functions are interrupted by signals when they are called (judging whether Enno equals eintr when the function returns).
But the principle of processing the signal in multi-threading is completely different, and the basic principle is: to process the signal asynchronously,
convert to synchronous processing, which means that a thread is dedicated to the arrival of a "synchronous wait" signal, while other threads can be completely disconnected/interrupted by the signal (interrupt). This simplifies the processing of signals in a multithreaded environment to a considerable extent. It is also possible to ensure that other threads are not affected by the signal. So we can fully predict the signal, because it is no longer asynchronous, but synchronous (we know exactly which execution point in the thread the signal will come in and be processed!) )。 Synchronous programming patterns are always simpler than asynchronous programming patterns. In fact, multi-threading compared to one of the advantages of multi-process is: Multithreading can be asynchronous in the process of converting things into synchronous processing.
1. sigwait function:
- Sigwait-wait for a signal
- #include <signal.h>
- int sigwait (CONST sigset_t *set, int *sig);
Description
- The sigwait () function suspends execution of the calling thread until the delivery of one
- Of the signals specified in the signal set set. The function accepts the signal (removes
- It from the pending list of signals), and returns the signal number in sig.
- The operation of Sigwait () is the same as Sigwaitinfo (2), except that:
- * SIGWAIT () only returns the signal number, rather than a siginfo_t structure describing
- The signal.
- * The return values of the functions are different.
- Return Value
- On success, sigwait () returns 0. On error, it returns a positive error number.
From the description of the man sigwait above, we know: Sigwait is
SyncWait for the signal to arrive, instead of waiting for the signal to be asynchronous like in the process. The sigwait function uses a signal set as his parameter, and returns the signal value when any signal in the set occurs, unblocking it, and can then perform some corresponding processing on the signal.
2. Remember:In multithreaded code, a function such as sigwait or Sigwaitinfo or sigtimedwait is always used to process the signal. Instead of functions such as signal or sigaction. Because a function called signal or sigaction in one thread changes the signal handler function in the thread. Instead of just changing the signal processing function of the thread that called Signal/sigaction.
3. Pthread_sigmask function:Each thread has its own set of signal masks (the signal mask),You can use the Pthread_sigmask function to block a thread from certain signalsresponse processing, leaving only the thread that needs to process the signal to process the specified signal. Implementation by using the inheritance relationship of the thread signal masking set(after the sigmask is set in the main process, the thread created by the main process inherits the mask of the main process)
- Pthread_sigmask-examine and change mask of blocked signals
- #include <signal.h>
- int pthread_sigmask (int how, Const sigset_t *Set, sigset_t *oldset);
- Compile and Link with-pthread.
- DESCRIPTION
- The Pthread_sigmask () function is a just like Sigprocmask (2), with the difference , it use
- In multithreaded programs are explicitly specified by posix.1-2001.
- Other differences is noted in the this page.
- For a description of the arguments and operation of this function, see Sigprocmask (2).
- RETURN VALUE
- On success, Pthread_sigmask () returns 0; On error, it returns an error number.
- NOTES
- A new thread inherits a copy of its creator ' s signal mask.
- (From Mans Sigprocmask:)
- The behavior of the dependent on the value of what, as follows.
- Sig_block
- The set of blocked signals is the union of the current set and the set argument.
- Sig_unblock
- The signals in set is removed from the current set of blocked signals. It is permissible
- To attempt to unblock a signal which are not blocked.
- Sig_setmask
- The set of blocked signals is set to the argument set.
- If oldset is Non-null, the previous value of the signal mask was stored in oldset.
- If Set is NULL and then the signal mask is unchanged (i.e., what is ignored)
- Value of the signal mask is nevertheless returned in Oldset (if it was not NULL).
4. Pthread_kill function:In a multithreaded program, a thread can use Pthread_kill to send a signal to a specified thread (including itself) in the same process. Note the KILL function is generally not used in multiple threads to send a signal because kill is sending a signal to the process, as a result: The running thread will process the signal, and if the thread does not register a signal handler, it will cause the entire process to exit.
- #include <signal.h>
- int Pthread_kill (pthread_t thread , int sig );
-
- Compile and link with-pthread.
-
- DESCRIPTION
- the Pthread_kill () function sends the SIGNAL&NBSP; sig to thread, Anoth Er thread in the same
- process as the caller. The signal is asynchronously directed to thread.
-
- if Sig is 0, then no signal was sent, but error checking was still performed; this can be& nbsp;
- used to check for the existence of a thread ID.
-
- RETURN VALUE
- on Success, Pthread_kill () returns 0; "On" error, it returns an Error number, and No signal
- is sent.
-
- ERRORS
- esrch No thread with the ID of thread could be found.
- EINVAL An invalid signal is specified.
5. Remember: The signal that calls the sigwait synchronous wait must be masked in the calling thread and should usually be masked in all threads (so that the signal is never sent to any other thread other than the call to Sigwait), which is achieved by using the inheritance relationship of the signal mask. (The semantics of sigwait require, all threads (including the thread calling sigwait) has the signal masked, for rel Iable operation. Otherwise, a signal, arrives not blocked in sigwait
might is delivered to another thread.)
6. Code example :(from Mans Pthread_sigmask)
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <errno.h>
- /* Simple error handling functions */
- #define Handle_error_en (en, msg) \
- do {errno = en, perror (msg); exit (exit_failure);} while (0)
- static void *
- Sig_thread (void *arg)
- {
- sigset_t *set = (sigset_t *) arg;
- int S, SIG;
- for (;;) {
- s = sigwait (set, &sig);
- if (s! = 0)
- Handle_error_en (S, "sigwait");
- printf ("Signal handling thread got Signal%d\n", SIG);
- }
- }
- int
- Main (int argc, char *argv[])
- {
- pthread_t thread;
- sigset_t set;
- int s;
- /*
- Block SIGINT; Other threads created by main () would inherit
- A copy of the signal mask.
- */
- Sigemptyset (&set);
- Sigaddset (&set, sigquit);
- Sigaddset (&set, SIGUSR1);
- s = Pthread_sigmask (Sig_block, &set, NULL);
- if (s! = 0)
- Handle_error_en (S, "pthread_sigmask");
- s = pthread_create (&thread, NULL, &sig_thread, (void *) &set);
- if (s! = 0)
- Handle_error_en (S, "pthread_create");
- /*
- Main thread carries on to create other threads and/or do
- Other work
- */
- Pause (); /* Dummy Pause so we can test program */
- return 0;
- }
Compile run:
- [Email protected]:~/pthread/learnthread$ gcc-wall-pthread-o pthread_sigmask pthread_sigmask.c
- [Email protected]:~/pthread/learnthread$./pthread_sigmask &
- [1] 4170
- [Email protected]:~/pthread/learnthread$ kill-quit%1
- [Email protected]:~/pthread/learnthread$ Signal handling thread got Signal 3
- [Email protected]:~/pthread/learnthread$ kill-usr1%1
- [Email protected]:~/pthread/learnthread$ Signal handling thread got Signal 10
- [Email protected]:~/pthread/learnthread$ kill-term%1
- [Email protected]:~/pthread/learnthread$
- [1]+ Terminated./pthread_sigmask
- [Email protected]:~/pthread/learnthread$
This example shows that by blocking some signals in the main thread, the other threads inherit the signal mask, and then use the Sigwait function exclusively with one thread to synchronously process the signal so that other threads are not affected by the signal.
Linux signals and multithreading