inter-process communication -- Signal
Tenet: The learning of technology is limited and the spirit of sharing is limitless.
First, Signals and interrupts
1. Basic Signal Concepts
(1) Send signal: Generate signal, there are many ways to send a signal "one process to another process, the kernel to the user, the process to itself"
(2) Installation signal: When the signal arrives, the default action is no longer performed, and the custom code is executed.
(3) Delivery signal: A signal is sent to the target process by the operating system to cause the execution of a certain segment of handlers.
(4) Capture signal: the signal being delivered causes the execution of a certain segment of the handler in the target process.
(5) Shielding signal: The process tells the operating system not to accept certain signals temporarily.
(6) Ignore the signal: the process is delivered to the target process, but the target process is not processed and discarded directly.
(7) Outstanding signal: Signal has been generated, but because the target process temporarily block the signal can not be captured by the target process signal.
(8) reliable signal and unreliable signal: the signal is less than 32 is unreliable signal, more than 32 is a reliable signal.
The "Pending" signal is a state that refers to the process from the generation of signals to the processing of signals before they are processed. The "shield" of a signal is a switching action, which means temporarily preventing the signal from being processed.
Enter the command kill–l to view a list of system-defined signals:
$ kill-l
1) SIGHUP 2) SIGINT 3) Sigquit 4) Sigill 5) SIGTRAP
6) SIGABRT 7) Sigemt 8) SIGFPE 9) SIGKILL) Sigbus
One) (SIGSEGV) (Sigsys) sigpipe) sigalrm) SIGTERM
Sigurg) (SIGSTOP) SIGTSTP Sigcont) SIGCHLD
(Sigttin) Sigttou () SIGIO) sigxcpu) Sigxfsz
(SIGVTALRM) sigprof) sigwinch SIGPWR) SIGUSR1
SIGUSR2) Sigrtmax
Second, send the signal
Sending a signal refers to a process that sends a signal value to another process, but is not actually sent directly but is forwarded by the OS. There are several situations in which a signal is generated:
(1) The user presses CTRL-C, this keyboard input produces a hardware interrupt.
(2) The hardware abnormal produces the signal. Generates a SIGSEGV for an invalid storage access process
(3) terminate the process signal. Other processes call the Kill () function to send a signal to another process or process group.
(4) The software abnormal produces the signal.
1. Kill send a signal to the process
--pass a signal to the specified process using the Kill () function, use raise () for the current process, wake-up settings timed using alarm ()
(1) Function prototypes
#include <signal.h>
Intkill (pid_t pid, int sig);
(2) Function parameters
PID: Process number (PID) to be passed the signal
Pid>0: A process that sends a signal to a process with PID values of PID
Pid=0: Sends a signal to all processes in the same process group as the current process
Pid=-1: Sends a signal to all processes within the system
Pid<0: Sends the signal to the process group number Pgid all signals of PID absolute value
SIG: The signal value sent
(3) Return value
Successful return 0, failure return-1
You can send a kill-0 signal to a process to detect whether a process exists because the current process always exists:
Kill (Getpid, 0);
2. Raise Bootstrap a signal
--sends a signal to the current process that wakes up a process.
(1) Function prototypes
#include <signal.h>
int raise (int sig);
(2) Function parameters
SIG: The signal value sent
(3) Return value
Successful return 0, failure return-1
This function is equivalent to:
if (Kill (Getpid (), sig) = =-1)
{
Perror ("raise");
}
3. Alarm timed
--Pass the timing signal, that is, in how much time produces the SIGALRM signal, the call produces a signal once.
(1) Function prototypes
#include <unistd.h>
int alarm (unsigned int seconds);
(2) Function parameters
Seconds: How much time to send the SIGALRM signal to the current process
Seconds=0: Cancels all alarm requests issued
(3) Return value
No alarm was called before calling Alarm, 0 was successfully returned, and the failure returned-1;
Having previously called the alarm function, the alarm for the calling process will be reset, successfully, based on the current time, and the return value of the last set alarm will generate the SIGALRM signal in the amount of time.
4. Ualarm timed
--Causes the current process to generate a SIGALRM signal within a specified time, and then repeats the SIGALRM signal every specified time.
(1) Function prototypes
useconds_t ualarm (useconds_t value,useconds_t interval);
(2) Function parameters
Value: SIGALRM signal generated within the specified time (US)
Interval: SIGALRM is repeated every specified time
(3) Return value
Successfully returned 0,
Three, installation signal and capture signal
1. Signal Processing Methods
(1) Ignore this signal.
(2) Perform the default processing action for this signal.
(3) A signal processing function is provided, which requires the kernel to switch to the user state to execute this processing function when processing the signal, which is called catch (catch) signal.
2. Signal Installation Signal
--the signal has a default processing, no special processing, the default action will be performed; To do special processing, the signal processing function is installed.
(1) Function prototypes
#include <signal.h>
typedef void (*sighandler_t) (int);
sighandler_t signal (int sig, Sighandlerhandler);
(2) Function parameters
SIG: Received Signal
Handler: Processing code entry after receiving this signal
(3) Return value
A successful return points to the last setting for this signal, and the execution failed to return a sig_eer (-1) error.
3. sigaction Installation Signal
--signal can only provide simple signal installation operations, and gradually and eliminated. This function can be used to check and change signal processing operations.
(1) Function prototypes
#include <signal.h>int sigaction (int signo, const struct sigaction *act, struct sigaction *oact); struct sigaction{< C0/>void (*sa_handler) (int);/* Addr of signal handler, */ * or sig_ign, or sig_dfl*/ sigset_t sa_mask;/*addition Al signals to block * /int sa_flags;/* signaloptions, Figure 10.16 */ * Alternate handler /void (*SA_SIGAC tion) (int, siginfo_t *, void *);};
(2) Function parameters
Signo: Specify the number of the signal
If the act pointer is not empty, the processing action of the signal is modified according to act. If the oact pointer is not empty, the original processing action of the signal is transmitted through the oact.
(3) Return value
Successful return 0, Failure returns-1.
Assigning a value of Sa_handler to a constant sig_ign to sigaction means ignoring the signal, assigning a constant SIG_DFL representing the system default action, assigning a function pointer to the signal with a custom function, or registering a signal handler function with the kernel. The function return value is void, can take an int parameter, through the parameter can know the current signal number, so you can use the same function to handle a variety of signals. Obviously, this is also a callback function, not called by the main function, but is called by the system.
When the processing function of a signal is called, the kernel automatically joins the current signal to the signal screen word of the process, and when the signal processing function returns, the original signal screen word is automatically restored, so that when a signal is processed, if the signal is generated again, it will be blocked until the current processing ends. If the signal processing function is called, in addition to the current signal is automatically shielded, but also want to automatically block other signals, the Sa_mask field is used to illustrate these signals that require additional shielding, when the signal processing function returned automatically restore the original signal mask word. The Sa_flags field contains some options, I set Sa_flags to 0, and sa_sigaction is the processing function for real-time signals.
Four, Signal set operation
Signal ignore: The system still transmits the signal, indicating that the corresponding process does not do any processing of the signal.
Signal masking: The process does not capture a signal even if it passes the signal to the process.
#define SIGSET_NWOEDS (1024x768/(8 * sizeof (unsigned long int))) typedef struct{ unsigned long int val[sigset_nwoeds];} s igset_t;
1. Sigprocmask
--Set process masking signal set
(1) Function prototypes
#include <signal.h>
int sigprocmask (int how, const sigset_t *set, sigset_t *oset);
(2) Function parameters
If the Oset is a non-null pointer, the current signal screen word of the read process is passed through the Oset parameter. If the set is a non-null pointer, the signal mask word for the process is changed, and the parameter how indicates how to change it. If both the Oset and the set are non-null pointers, the original signal shielding word is backed up into the oset, and the signal screen word is changed according to the set and how parameters. Assuming that the current signal mask is mask, the following table describes the optional values for the How parameter.
Sig_block |
The set contains the signal we want to add to the current signal mask, equivalent to Mask=mask|set |
Sig_unblock
|
The set contains the signals we want to unblock from the current signal mask, equivalent to Mask=mask&~set |
Sig_setmask |
Sets the value pointed to by the current signal screen word set, which is equivalent to Mask=set |
(3) Return value
0 if successful, 1 if there is an error
2. sigpending
#include <signal.h>
int sigpending (sigset_t *set);
--Read the outstanding signal set of the current process and pass through the set parameters. A successful call returns 0, and an error returns-1.
#include <signal.h> #include <stdio.h> #include <unistd.h>void printsigset (const sigset_t *set) { int i; for (i = 1; i < i++) if (Sigismember (set, i) = = 1) { Putchar (' 1 '); } else { Putchar (' 0 '); } Puts ("");} int main (void) { sigset_t S, p; Sigemptyset (&s); Sigaddset (&s, SIGINT); Sigprocmask (Sig_block, &s, NULL); while (1) { sigpending (&p); Printsigset (&p); Sleep (1); } return 0;} <span style= "font-family:arial, Helvetica, Sans-serif; Background-color:rgb (255, 255, 255); " > </span>
3. Signal Set
#include <signal.h>int sigemptyset (sigset_t *set); int Sigfillset (sigset_t *set); int Sigaddset (sigset_t *set, int SIGNO); int Sigdelset (sigset_t *set, int signo); int sigismember (const sigset_t *set, int signo);
The function Sigemptyset initializes the set of signals that the set points to, so that the corresponding bit of all the signals is zeroed, indicating that the signal set does not contain any valid signals. The function Sigfillset initializes the set of signals that the set points to, so that the corresponding bit of all the signals is placed, indicating that the valid signal of the signal set includes all signals supported by the system. Note that before using a variable of type sigset_t, be sure to call Sigemptyset or Sigfillset to initialize it so that the signal set is in a determined state. After initializing the sigset_t variable, you can add or remove a valid signal from the signal set by calling Sigaddset and Sigdelset. All four functions return 0 successfully, and an error returns-1. Sigismember is a Boolean function that is used to determine whether a signal set in the valid signal contains a certain signal, if included is returned 1, does not contain the return 0, an error returns-1.
V. Wait for the signal
The process can be blocked by waiting for certain signals, and the pause () function waits for any signal other than the current process, while Sigsuspend () waits for any signal other than the specified signal.
1 , Pause
--suspends the calling process until a signal is reached
(1) Function prototypes
#include <unistd.h>
int pause (void);
(2) Parameter return value
If the signal processing action is to terminate the process, then the process terminates, the pause function does not have a chance to return, if the signal processing action is ignored, the process continues to be suspended, pause does not return, if the signal processing action is capture, then call the signal processing function after pause return-1, Errno is set to Eintr, so pause has only the return value of the error.
Use alarm and pause to implement sleep (3) function # include <unistd.h> #include <signal.h> #include <stdio.h>void sig_alrm ( int signo) { /* Nothing to do */}unsigned int mysleep (unsigned int nsecs) { struct sigaction newact, oldact; unsigned int unslept; Newact.sa_handler = SIG_ALRM; Sigemptyset (&newact.sa_mask); newact.sa_flags = 0; Sigaction (SIGALRM, &newact, &oldact); Alarm (nsecs); Pause (); unslept = alarm (0); Sigaction (SIGALRM, &oldact, NULL); return unslept;} int main (void) { while (1) { mysleep (2); printf ("secondspassed\n"); } return 0;}
(1) The main function calls the Mysleep function, which calls Sigaction to register the handler function Sig_alrm of the SIGALRM signal.
(2) Call alarm (NSECS) to set the alarm.
(3) Call pause to wait for the kernel to switch to another process to run.
(4) After nsecs seconds, the alarm clock expires, the kernel sends SIGALRM to this process.
(5) processing the pending signal from the kernel state before returning the user state of the process, and discovering the SIGALRM signal, whose processing function is SIG_ALRM.
(6) switch to the user state execution Sig_alrm function, enter the SIG_ALRM function SIGALRM signal is automatically shielded, from the SIG_ALRM function return SIGALRM signal automatically unblock. It then automates the system call Sigreturn again into the kernel and returns to the main control flow (the Mysleep function called by the main function) of the user state to continue executing the process.
(7) The Pause function returns-1, and then calls alarm (0) to cancel the alarm, calling Sigaction to restore the previous processing of the SIGALRM signal.
reentrant Function-- a function that is not reentrant if one of the following conditions is met:
malloc or free is called because malloc also manages the heap with a global list.
A standard I/O library function was called. Many implementations of the standard I/O library use global data structures in a non-reentrant manner.
"Popular says: The use of global variables are non-reentrant"
Inter-process communication-signal