Communication between Linux Environment (2): Signals (below)

xiaoxiao2021-03-06  117

Communication between Linux Environment (2): Signals (below)

content:

Signal lifecycle signal programming precautions in depth: signal application example reference information about the author

related information:

Inter-Linux Environment Process (1): Pipeline and Among the Linux Environment Process Communication (2): Signals (on)

In the Linux area:

Tutorial Tools & Product Codes & Component Articles

Zheng Yanxing (mlinux@163.com) January 2003

In the signal (on), the Linux signal type, source, how to install a signal, and the operation of the signal set. This section first discusses the signal of the signal from the life cycle of the signal, or a simple signal mechanism that seems to be similar (after the process receives the signal, it seems to be simply simpler), how is micro-optimistic? It is also understood by deeper levels. Some precautions for signal programming will be discussed next, and some instances of signal programming are given.

First, the signal lifecycle can be divided into three important phases for the execution of the signal life cycle to the signal processing function, which can be divided into three important phases for a complete signal lifecycle (after execution of the signal to the corresponding processing function). Managed by four important events: the signal is born; the signal is registered in the process; the signal is completed in the process; the signal processing function is executed. The interval between the two events constitutes a stage of the signal lifecycle. The practical significance of the four events is described below:

The signal "was born". The birth of the signal refers to the event of a trigger signal (such as detected hardware abnormality, timer timeout, and call signal send function kill () or sigqueue (), etc.). Signals "Register" in the target process; there is a data member of the unconscious signal in this process in the process of the process: struct Sigpending Pending: SIGPENDING:

Struct Sigpending {

Struct Sigqueue * head, ** tail;

Sigset_t signal;

}

The third member is all unresser in the process, first, the second member points to a structural chain of a sigqueue type (called "unconscious signal information chain"), each of the information chain, each of the SigQueue The structure portrayes the information carried by a particular signal, and points to the next Sigqueue structure: struct sigqueue {

Struct Sigqueue * Next;

SigInfo_T info;

}

The signal is registered in the process that the signal value is added to the pending signal set of the process (the second member sigset_t signal of the SIGPENDING structure), and the information carried by the signal is retained to a sigqueue structure of the unreasonable signal information chain. . As long as the signal is in the unrespoated signal concentration of the process, it indicates that the process already knows the presence of these signals, but it has not been processed, or the signal is blocked. Note: When a real-time signal is sent to a process, regardless of whether the signal is registered in the process, it will be registered again, so the signal will not be lost, so the real-time signal is called "reliable signal". This means that the same real-time signal can occupy multiple SIGQUEUE structures in the unreasonable signal information chain of the same process (each received a real-time signal, will allocate a structure to register the signal information, add this structure. In the unreasonable signal chain, that is, all birth real-time signals are registered in the target process; when a non-real-time signal is sent to a process, if the signal has been registered in the process, the signal will be discarded, resulting in signals Lost. Therefore, non-real-time signals are called "unreliable signals". This means that the same non-real-time signal is in the unrespoated signal information chain of the process, with a Sigqueue structure (after a non-real-time signal is born, (1), if the same signal is found, it is no longer registered in the target structure. Registration, for the process, it is equivalent to not knowing that this signal occurs, the signal is lost; (2) If there is no other signal in the promised signal, you register yourself in the process). The signal is logged out in the process. During the implementation of the target process, it is detected whether there is a signal waiting processing (such a check is made each time it is returned from the system space to the user space). If there is a signal waiting to be processed and the signal is not blocked, the process is removed from the structure occupied in the unreasonable signal chain before running the corresponding signal processing function. Whether to delete the signal from the process unrequited signal concentration for real-time and non-real-time signals. For non-real-time signals, since up to only one SIGQUEUE structure in the unconscious signal information chain, the structure is released, and the signal should be deleted in the process unrequited signal (the signal is completed); and for real-time signals Say, it is possible to occupy multiple SIGQUEUE structures in the unrescribed signal information chain, so treating the number of SIGQUEUE structures should be taken: If only one SIGQUEUE structure (the process only receives this signal once), the signal should be in the process. Unreported Signal Concentration Deletion (Signal Logout is completed). Otherwise, the signal should not be deleted in the unreasonable signal of the process (the signal is completed). The process first deresses the signal in the process before executing the signal corresponding to the function. Signal life termination. After the process logs out, immediately perform the corresponding signal processing function, after the execution is completed, the impact of the signal is completely ended. Note: 1) Signal registration or not, with the function of the transmitted signal (such as kill () or sigqueue (), etc.) and the signal installation function (Signal () and sigction ()) are only related to the signal value (the signal value is less than Sigrtmin) The signal is only only registered once, the signal value is between Sigrtmin and Sigrtmax, as long as it is received by the process, is registered).

2) During the signal being logged out to the corresponding signal processing function, if the process receives the same signal multiple times, the real-time signal is registered every time; for non-real-time signals Say, no matter how many times received, it will be considered only a signal, only registered in the process. Second, the signal programming precautions prevents loss of signals that should not be lost. If you understand the signal life cycle mentioned in Eighth, it is easy to know that the signal will not be lost, and where to lose. The portability of the program takes into account the portability of the program, should try to use the POSIX signal function, and the POSIX signal function is mainly divided into two categories:

POSIX 1003.1 Signal Function: Kill (), SigAction (), SigaddSet (), Sigdelset (), SiGemptySet (), SIGFILLSET (), SIGISMEMBER (), SIGPENDING (), SigProcmask (), Sigsuspend (). POSIX 1003.1B signal function. POSIX 1003.1B extension POSIX 1003.1 in terms of the real-time performance of the signal, including the following three functions: sigqueue (), SigtimedWait (), SigwaitInfo (). Where Sigqueue is primarily transmitted for signal transmission, and SigtimedWait and Sigwaitinfo () are primarily used to replace the sigsuspend () function, and there is a corresponding instance later. #include

INT Sigwaitinfo (SigSet_t * set, siginfo_t * info).

This function is similar to sigsuspend (), blocks a process until a specific signal occurs, but the signal processing function is not executed, but the signal value is returned. Therefore, in order to avoid the implementation of the corresponding signal processing function, it is necessary to block the SET point to the signal before calling the function, so the typical code called the function is: sigset_t newmask;

INT RCVD_SIG;

SigInfo_T info;

SiGemptySet (& newmask);

SigaddSet (& newmask, sigrtmin);

SigProcmask (SIG_BLOCK, & NewMask, NULL);

RCVD_SIG = SigwaitInfo (& newmask, & info)

IF (rcvd_sig == -1) {

.

}

The call successfully returns the signal value, otherwise returns -1. SigtimedWait () features Similar, but increases the time of a process waiting. The stability of the program. In order to enhance the stability of the program, a reusable function should be used in the signal processing function. The reuse (reusable) function should be used in the signal handler (Note: The so-called reusable function refers to a process that can be called by multiple tasks, and the task does not have to worry about whether the data will be wrong when calling. Because the process is after receiving the signal, the jump to the signal processing function will be executed. If you use an unremissible function in the signal processing function, the signal processing function may modify the data that should not be modified in the original process so that the process may occur when it returns to the signal from the signal processing function, may appear unpredictable consequences. The reusable function is considered an unsafe function in the signal processing function. Most of the functionality that meet the following conditions is non-renewable: (1) Use a static data structure, such as getLogin (), gmtime (), getGrgid (), getGRNAM (), getpwuid (), and getPwnam (), etc. (2) When the function is implemented, the malloc () or free () function is called; (3) The standard I / O function is used when implemented.

The Open Group is revealed by the following functions: _exit (), Access (), ALARM (), cfgetispeed (), cfgetospeed (), cfsetispeed (), cfsetospeed (), chdir (), chmod (), chown ), CLOSE (), Creat (), DUP (), DUP2 (), Execle (), Execve (), FCNTL (), fork (), fSync (), fst (), fsync (), getEgId (), GetEuid (), getGID (), getGroups (), getPGRP (), get regi (), getppid (), getuid (), kill (), link (), lseek (), mkdir (), MKFIFO (), Open ( ), Pathconf (), PAUSE (), PIPE (), RAISE (), RET (), RENAME (), RMDIR (), setGID (), setpgid (), setsid (), setuid (), SIGAction (), sigaddset (), SIGEMPTYSET (), SIGEMPTYSET () () SIGEMPTYSET () () SIGFILLSET (), SIGISMEMBER (), SIGNAL (), SIGSMEMBER (), SIGPROCMASK (), Sigsuspend (), SLEEP (), STAT (), Sysconf (), TcDrain ), Tclow (), tclush (), tcgettr (), tcsen, tcsettt (), tcsetpgrp (), TIME (), TIMES (), umask (), unplan (), unlink ()

Utime (), WAIT (), WaitPid (), Write (). Even if the signal processing function is "secure function", it is also necessary to pay attention to enter the processing function, first save the value of Errno, and then restore the original value. Because, the errno value may be changed at any time during the signal processing. In addition, longjmp () and siglongjmp () are not listed as a reusable function, because it is safe to ensure that other calls that follow the two functions are safe. Third, in-depth shallow: Signal application examples of signal applications under Linux do not imagine so horror, programmers have to do only three things: installation signal (recommended using sigAction ()); implement three-parameter signal processing function, Handler (intler) Signal, Struct SigInfo * Info, Void *); Send Signal, recommend Sigqueue (). In fact, for some signals, as long as the installation signal is sufficient (the signal processing mode is default or ignored). Other can be done is nothing more than a few operations related to the signal set. Example 1: Signal transmission and processing Implement a signal reception program SigReceive (where signal is installed by sigAction ()). #include

#include

#include

Void new_op (int, siginfo_t *, void *);

INT main (int Argc, char ** argv)

{

Struct SigAction Act;

Int Sig;

SIG = ATOI (Argv [1]);

SiGemptySet (& Act.sa_mask);

Act.sa_flags = sa_siginfo;

Act.sa_sigAction = new_op;

IF (SIGACTION (SIG, & ACT, NULL <0)

{

Printf ("Install Sigal Error / N);

}

While (1)

{

Sleep (2);

Printf ("Wait for the Signal / N);

}

}

Void new_op (int signum, siginfo_t * info, void * myact)

{

Printf ("Receive Signal D", Signum);

Sleep (5);

}

Explanation, the command line parameter is the signal value, the background runs Sigreceive Signo &, the ID of the process can be obtained, assuming to PID, and then running the Kill -S Signo PID verification signal on another terminal. Receive and processing. At the same time, the queuing problem of the signal can be verified. Note: You can use SigQueue to implement a command line signal sender SIGQUEUESEND, see Appendix 1. Example 2: Signal delivery additional information mainly includes two instances:

Send a signal to the process itself and transmit pointer parameters; #include

#include

#include

Void new_op (int, siginfo_t *, void *);

INT main (int Argc, char ** argv)

{

Struct SigAction Act;

Union sigval mysigval; int i;

Int Sig;

PID_T PID;

Char Data [10];

MEMSET (DATA, 0, SIZEOF (DATA);

For (i = 0; i <5; i )

DATA [I] = '2';

mysigval.sival_ptr = data;

SIG = ATOI (Argv [1]);

PID = getPid ();

SiGemptySet (& Act.sa_mask);

Act.sa_sigAction = new_op; // three-parameter signal processing function

Act.sa_flags = sa_siginfo; // Information transfer switch

IF (SIGACTION (SIG, & ACT, NULL <0)

{

Printf ("Install Sigal Error / N);

}

While (1)

{

Sleep (2);

Printf ("Wait for the Signal / N);

SIGQUEUE (PID, SIG, MYSIGVAL); / / Send a signal to this process and pass additional information

}

}

Implementation of Void New_op (int Signum, SigInfo_t * info, void * myact) // three-parameter signal processing function

{

INT I;

For (i = 0; i <10; i )

{

Printf ("% C / N", (* ((* INFO) .si_ptr) i)))))))

}

Printf ("Handle Signal% D Over;", Signum);

}

In this example, the signal implements the delivery of additional information, and how the signal is processed for these information depends on the specific application. 2. Transfer Establishment Parameters between different processes: Putting the signals in 1 in two programs, and transmitting the integer parameters during the transmission process. Signal receiver: #include

#include

#include

Void new_op (int, siginfo_t *, void *);

INT main (int Argc, char ** argv)

{

Struct SigAction Act;

Int Sig;

PID_T PID;

PID = getPid ();

SIG = ATOI (Argv [1]);

SiGemptySet (& Act.sa_mask);

Act.sa_sigAction = new_op;

Act.sa_flags = sa_siginfo;

IF (SIGACTION (SIG, & ACT, NULL <0)

{

Printf ("Install Sigal Error / N);

}

While (1)

{

Sleep (2);

Printf ("Wait for the Signal / N);

}

}

Void new_op (int signum, siginfo_t * info, void * myact)

{

Printf ("THE INT VALUE IS% D / N", INFO-> Si_INT);

}

Signal Send Program: The second parameter of the command line is the signal value, and the third parameter is the receiving process ID. #include

#include

#include

#include

Main (int Argc, char ** argv)

{

PID_T PID;

Int Signum; Union Sigval mysigval;

Signum = ATOI (Argv [1]);

PID = (PID_T) ATOI (Argv [2]);

mysigval.sival_int = 8; // does not represent specific meaning, only for explanation

IF (Sigqueue (PID, Signum, MySigval == - 1)

Printf ("Send Error / N");

Sleep (2);

}

Note: The two examples of Example 2 focus on the signal to deliver information. At present, there are very few examples of transmitting information under Linux, but there is some unix, but the passed is basically about delivering an integer, transmitting I haven't seen it yet. I have not implemented a pointer delivery between different processes (actually more meaningful), maybe there is a problem in implementing the method, please realize Email me.

Example 3: Signal blocking and signal set operation #include "signal.h"

#include "unistd.h"

Static void my_op (int);

Main ()

{

SigSet_t new_mask, old_mask, pending_mask;

Struct SigAction Act;

SiGemptySet (& Act.sa_mask);

Act.sa_flags = sa_siginfo;

Act.sa_sigAction = (void *) my_op;

IF (Sigction (Sigrtmin 10, & act, null)

Printf ("Install Signal Sigrtmin 10 Error / N");

SiGemptySet (& new_mask);

SigaddSet (& new_mask, sigrtmin 10);

IF (SigProcmask (SIG_BLOCK, & New_MASK, & OLD_MASK))

Printf ("BLOCK SIGNAL SIGRTMIN 10 ERROR / N");

Sleep (10);

Printf ("Now Begin TO GET PENDING MASK AND UNBLOCK SIGRTMIN 10 / N");

IF (SIGPENDING (& PENDING_MASK) <0)

PRINTF ("Get Pending Mask Error / N);

IF (Sigismember (& PENDING_MASK, SIGRTMIN 10))

Printf ("Signal Sigrtmin 10 IS Pending / N");

IF (SigProcmask (SIG_SETMASK, & OLD_MASK, NULL) <0)

Printf ("UNBLOCK SIGNAL ERROR / N");

Printf ("Signal UNBLOCKED / N");

Sleep (10);

}

Static void my_op (int signum)

{

Printf ("Receive Signal D / N", SIGNUM);

}

Compile this procedure and operate in an insert. Send a signal to the process (running kill -s 42 pid, sigrtmin 10), and the results can see the operation mechanism of several critical functions, and the signal set related operation is relatively simple. Note: In the above examples, the Printf () function is used, but as a diagnostic tool, the Pringf () function is not rebarned and should not be used in the signal processing function. Conclusion: The system is analyzed to analyze the Linux signaling mechanism. Summary makes me benefit! Thanks to Wang Xiaole and other netizens! Comments and Suggestions Area! Appendix 1: The command line signal transmitter SigQueuesend implemented by the SigQueue, the second parameter of the command line is the signal value transmitted, the third parameter is the process ID of the signal, which can be used in conjunction with example : #Include #include

#include

INT main (int Argc, char ** argv)

{

PID_T PID;

Int Sig;

SIG = ATOI (Argv [1]);

PID = ATOI (Argv [2]);

SIGQUEUE (PID, SIG, NULL);

Sleep (2);

}

references:

linux kernel source code Scenario Analysis (on), Maud parade, Hu Ximing with Zhejiang University Press, when you want to verify a conclusion, when the idea of ​​the best reference materials; UNIX high-level programming environment, Author: W.Richard Stevens, translator : Yugukan, etc., Machinery Industry Press. The more detailed details of the development process of the signal mechanism. Signal, SigAction, Kill, etc., the most direct and reliable reference. http://www.linuxjournal.com/modules.php?op=modload&name=ns-help&file=man provides online guidelines such as many system calls, library functions, and more. Http://www.opengroup.org/onlinepubs/007904975/ You can query many key functions (including system calls) here, very good URL. http://unix.org/WhitePapers/reeTrant.html elaborates the functions of the function. http://www.uccs.edu/~compsvcs/doc-cdrom/docs/html/aps33dte/docu_006.htm gives a considerable description of the real-time signal.

About the author Zheng Yanxing, National Defense Science and Technology University attacked a doctorate. Contact: mlinux@163.com.

转载请注明原文地址:https://www.9cbs.com/read-103773.html

New Post(0)