About Linux IPC (vii): signal (UP)

Source: Internet
Author: User
Tags signal handler

"Copyright Notice: respect for the original, reproduced please retain the source: blog.csdn.net/shallnet or .../gentleliu, the article is for learning communication only, do not use for commercial purposes" the signal is similar to an interrupt request, and a process does not block waiting for a signal to arrive at some point, Also do not know when the signal will come, the signal generation is random, the process only need to register signal processing function, when the signal arrives to execute the signal processing function. The signals supported by the Linux system can be viewed by command kill-l:
# kill-l 1) SIGHUP 2) SIGINT 3) Sigquit 4) Sigill 5) SIGTRAP 6) SIGABRT 7) Sigbus 8) SIGFPE 9) SIGKILL) SIGUSR1) SI GSEGV) (SIGUSR2) sigpipe) (SIGALRM) SIGTERM) sigstkflt) SIGCHLD) Sigcont (SIGSTOP) SIGTSTP) SI Gttin) (Sigttou) (Sigurg) (SIGXCPU) sigxfsz) sigvtalrm) sigprof) sigwinch SIGIO) SIGPWR S) (sigrtmin) (sigrtmin+1) (sigrtmin+2), sigrtmin+3) sigrtmin+4-sigrtmin+5) sigrtmin+6 42 ) (sigrtmin+8) (sigrtmin+9) (sigrtmin+10) sigrtmin+11) sigrtmin+12 (sigrtmin+13) sigrtmin+14) SIGRTMIN+1 (5) SIGRTMAX-14) SIGRTMAX-13 (SIGRTMAX-12) (SIGRTMAX-11) SIGRTMAX-10) SIGRTMAX-9) SIGRTMAX-8 AX-7) (SIGRTMAX-6) SIGRTMAX-5) SIGRTMAX-4 () SIGRTMAX-3) SIGRTMAX-2) SIGRTMAX-1 #
whichSigrtmin The front signal is a signal supported by the early UNIX, is unreliable signal, the back signal (Sigrtminto theSigrtmax ) for later addition, for reliable signals. The reliability of the signal on Linux is mainly reflected in whether the signal supports queueing, and the signal that does not support queuing may be lost.
There may be a lot of signals, such as: 1. The user presses CTRL + C to generate the interrupt signal (SIGINT );2. A hardware exception generates a signal, such as a divisor of 0, which accesses the memory illegally (SIGSEGV) and so on;3. Send signals using system commands, such as Kill-s <signo> <pid>, and send a signal with a value of Signo to process number PID process;4. Callthe Kill function, and other functions that can send a signal, send a signal to the specified process. Functions that can send signals are: alarm () andSetitimer ()SendSIGALRM Signal, abort () SendSIGABRTsignal, raise sends arbitrary signals to the process itself, and the kill function sends arbitrary signals to other processes or to its own processes.
There are three ways that processes receive signal processing:1. Ignore the signal; Most signals can be ignored, except for two types of signals: Sigkill and Sigstop. 2. Perform the system default operation; The default action for most signals is to terminate the process. 3. Capture the signal and execute the signal processing function, i.e. execute the user's own defined function when the signal is received.
The register signal handler function can use the function signal:
       #include <signal.h>       typedef void (*sighandler_t) (int);       sighandler_t signal (int signum, sighandler_t handler);
The parameter signum is the signal to register the handler function, the handler is the handler function for the signal (parameter one) or Sig_ign or SIG_DFL, if the parameter is SIG_DFL, the process will perform the default action if it is sig_ign, and if the process will ignore the signal, If it is a signal handler, the process will execute the function when it receives the signal and pass the parameter signum to the function;
To send a signal you can use the Kill function:
       #include <sys/types.h>       #include <signal.h>       int Kill (pid_t pid, int sig);
The parameter PID is the signal to be sent to the target process Id,sig,when it is 0 o'clock (that is, an empty signal), no signal is actually sent, but the error is checked as usual, so that it can be used to check whether the target process exists and whether the current process has permission to send a signal to the target (the root permission process can send a signal to any process, A non-root process can only send a signal to a process that belongs to the same session or to the same user.
value of parameter PID reception process of the signal
Pid>0 Process with process ID PID
Pid=0 Processes for the same process group
Pid<-1 Process group ID for all processes with-pid
Pid=-1 All processes that send a signal permission to the target process except for process 1

If it's the IPC, then a parent-child process through the signal to achieve simple communication program, that is, the parent process sends a signal to the child process, the child process received a signal after the execution of signal processing functions.
void Sig_func (int signo) {printf ("====%s== [child] handle Signo:%d===\n", __func__, Signo);}    void Child_process_do (void) {printf ("====%s==child pid:%d===\n", __func__, Getpid ()); Signal (sigrtmin, sig_func);    Child process registration signal sigrtmin processing function Sig_func//signal (SIGALRM, Sig_func);    while (1) {sleep (10);    }}void Parent_process_do (pid_t pid) {int i; Sleep (1); Wait for the child process to register the signal processing function first, or if the system first calls the parent process to execute first, after the call to kill the child process will exit, do not see the effect we need printf ("====%s==parent pid:%d===\n", __func__, Getpid    ()); for (i = 0; i < 5; i++) {printf ("====%s==[parent] send signal <%d> to PID <%d>==\n", __func__, SIGR        TMIN, PID); Kill (PID, sigrtmin);        The parent process sends a sigrtmin signal//kill (PID, SIGALRM) to the child process every second continuously;    Sleep (1); } waitpid (PID, NULL, 0);    The parent process waits for the child process to end}int main (int argc, const char *argv[]) {pid_t pid;    PID = fork ();        if (PID < 0) {fprintf (stderr, "fork:%s\n", Strerror (errno));    return-1; } if (0 = = pid) {CHILD_PROCESS_DO ();//Child process} else {PARENT_PROCESS_DO (PID);//Parent process} return 0;} 
at run time, the parent process sends 5 signals to the child process, which the child process receives and processes. #./target_bin====child_process_do==child pid:7072=======parent_process_do==parent pid:7071=======parent_process_do==[parent] Send signal <34> to PID <7072>======sig_func== [child] handle signo:34=======parent_process_do==[parent] Send signal <34> to PID <7072>======sig_func== [child] handle signo:34=======parent_process_do==[parent] Send signal <34> to PID <7072>======sig_func== [child] handle signo:34=======parent_process_do==[parent] Send signal <34> to PID <7072>======sig_func== [child] handle signo:34=======parent_process_do==[parent] Send signal <34> to PID <7072>======sig_func== [child] handle signo:34===
now in this program a little modification, let the child process in processing signal processing function with sleep for a period of time, here we can test whether the signal supports queuing. Modify the signal processing function to read as follows:
void Sig_func (int signo) {    sleep (6);    
Re-run:
#./target_bin====child_process_do==child pid:7159=======parent_process_do==parent Pid:7158=======parent_process_ Do==[parent] Send signal <34> to PID <7159>======parent_process_do==[parent] Send signal <34> to PID < ; 7159>======parent_process_do==[parent] Send signal <34> to PID <7159>======parent_process_do==[ Parent] Send signal <34> to PID <7159>======parent_process_do==[parent] Send signal <34> to PID <7159 >======sig_func== [child] handle signo:34=======sig_func== [child] handle signo:34=======sig_func== [child] handle S igno:34=======sig_func== [child] handle signo:34=======sig_func== [child] handle signo:34===
You can find that the signal sigrtmin supports queueing, and after the parent process has sent all the signals, the child process can still start processing all the signals before the parent process, and the signal is not lost. Now after modifying the code to test whether the signal before Sigrtmin supports queueing, we modify the child process and the parent process code as follows:
void Child_process_do (void) {    printf ("====%s==child pid:%d===\n", __func__, Getpid ());    Signal (sigrtmin, sig_func);    Signal (SIGALRM, sig_func);    while (1) {        sleep (ten);    }} void Parent_process_do (pid_t pid) {    int i;    Sleep (1);    printf ("====%s==parent pid:%d===\n", __func__, Getpid ());    for (i = 0; i < 5; i++) {        printf ("====%s==[parent] send signal <%d> to PID <%d>==\n", __func__, Sigrtm In, PID);        Kill (PID, sigrtmin);        Kill (PID, SIGALRM);        Sleep (1);    }    Waitpid (PID, NULL, 0);}

The results of the implementation are as follows:
#./target_bin====child_process_do==child pid:7259=======parent_process_do==parent Pid:7258=======parent_process_ Do==[parent] Send signal <34> to PID <7259>======parent_process_do==[parent] Send signal <34> to PID < ; 7259>======parent_process_do==[parent] Send signal <34> to PID <7259>======parent_process_do==[ Parent] Send signal <34> to PID <7259>======parent_process_do==[parent] Send signal <34> to PID <7259 >======sig_func== [child] handle signo:14=======sig_func== [child] handle signo:14===

When the next four signals are sent, the child process is busy processing the first signal, when the child process finished processing the first, the parent process has sent out all the signals, because the SIGALRM does not support queueing, the cache can only hold one signal, the middle three signal is lost, the child process will eventually only capture 2 signals. We re-modified the subprocess function to let the child process exit after 10 seconds, and the parent process receives the child process end signal after the child process exits and returns the last exit at Waitpid. Modify the child process code as follows:
void Sig_func (int signo) {    //sleep (6);    printf ("====%s== [child] handle Signo:%d===\n", __func__, Signo);} void Child_process_do (void) {    printf ("====%s==child pid:%d===\n", __func__, Getpid ());    Signal (sigrtmin, sig_func);    Signal (SIGALRM, sig_func);    /* while (1) {        sleep];    *    /Sleep (10);}

EXECUTE as follows:
#./target_bin====child_process_do==child pid:7450=======parent_process_do==parent Pid:7449=======parent_process_ Do==[parent] Send signal <34> to PID <7450>======sig_func== [child] handle SIGNO:14=======PARENT_PROCESS_DO ==[parent] Send signal <34> to PID <7450>======parent_process_do==[parent] Send signal <34> to PID <7 450>======parent_process_do==[parent] Send signal <34> to PID <7450>======parent_process_do==[parent] Send signal <34> to PID <7450>==

The result seems somewhat unexpected, and the child process exits when it receives a signal, but we have sleep for 10 seconds, which is why? The signal actually causes the return of sleep, so when the child process receives the first signal, it exits, so no child process is seen to process the signal behind. We can judge the return value of sleep, and when its return value is not equal to 0 o'clock, we continue to let it sleep. So let's change the laborious function of the sub-process to:
void Child_process_do (void) {    printf ("====%s==child pid:%d===\n", __func__, Getpid ());    Signal (sigrtmin, sig_func);    Signal (SIGALRM, sig_func);    /* while (1) {        sleep];    * * While    (sleep () > 0) {    }}
The result of this implementation is what we expected. This signal communication can only be one process to send a signal to another process, but can not carry information for data exchange, the next section we look at another signal, it can send a signal while transmitting some information. Download the source code for this section: http://download.csdn.net/detail/gentleliu/8193955

About Linux IPC (vii): signal (UP)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.