These days, a network traffic collector Program Basically changed. In the main function, after several sub-threads are started, the system goes to bed for 10 minutes and then cleans up the Sub-threads and exits. Now, if you want to change it to a subthread after it starts, the main thread enters infinite sleep until it receives the sigterm or SIGINT. The main program is as follows:
Other header files
# Include <signal. h> // header file required for Signal Processing
Int main (INT argc, char * argv []) {
// Other variable declarations
Sigset_t sig_set, sig_pending;
// Set signal blocking
Sigemptyset (& sig_set );
Sigaddset (& sig_set, sigterm );
Sigaddset (& sig_set, SIGINT );
Sigprocmask (sig_block, & sig_set, null );
Start several subthreads
...........
// Set signal blocking
Sigemptyset (& sig_set );
Sigaddset (& sig_set, sigterm );
Sigaddset (& sig_set, SIGINT );
Sigprocmask (sig_block, & sig_set, null );
// The main thread goes to sleep and waits for the signal to jump out of sleep
While (1 ){
Sigpending (& sig_pending );
If (sigismember (& sig_pending, sigterm) |
Sigismember (& sig_pending, SIGINT )){
Break;
}
Sleep (2 );
}
// Reasonable reason for sub-thread exit
................
Return 0;
}
After the program runs, it is very strange to find that the program exits immediately after pressing CTRL + C without the information of the Sub-thread exiting.
After careful analysis, the problem is that the characteristics of the multi-threaded model in Linux are ignored.
In Linux, a thread is essentially a light weighted process. When a thread is generated, a corresponding process control structure is generated, this structure shares the same process memory space with the process control structure of the parent thread. At the same time, the process control structure of the new thread will copy the same process information from the parent thread (process), such as opening the file list and blocking mask. Since the signal blocking mask is modified after the subthread is generated, the subthread uses the original process information of the main thread at this moment. Therefore, the subthread will still respond to the SIGINT and sigterm signals, therefore, when we use Ctrl + C to send a SIGINT signal, the main process does not process the signal, and the sub-process (thread) performs default processing, that is, exit. When a child process exits, it sends a sigchld signal to the parent process (thread), indicating that the child process exits. Because the signal is not blocked, the main process (thread) exits immediately, the preceding running condition occurs. Therefore, one solution to this problem is to set the signal before the subthread is generated, or set the signal inside the subthread. Since subthreads are often a transaction processing function, I suggest using the former in simple cases. If the signal to be processed is complicated, the last method must be used for processing. In this way, the above program logic can be changed to the following:
# Include <signal. h> // header file required for Signal Processing
Int main (INT argc, char * argv []) {
// Other variable declarations
Sigset_t sig_set, sig_pending;
Start several subthreads
...........
// The main thread goes to sleep and waits for the signal to jump out of sleep
While (1 ){
Sigpending (& sig_pending );
If (sigismember (& sig_pending, sigterm) |
Sigismember (& sig_pending, SIGINT )){
Break;
}
Sleep (2 );
}
// Reasonable reason for sub-thread exit
................
Return 0;
}