I. Signals and messages
The signals in Linux have the same energy as the messages below the win, all have a wide variety of signals (messages) and their corresponding signal (message) processing functions.
1. Signal processing function added.
Signal function.
The bottom is copied from advanced programming. The average is not strange, a look will understand.
Defined:
typedef void Sigfunc (int);
Sigfunc *signal (int, sigfunc *);
Binds a signal to his handler function. Very simple stuff. Under the wind, used a lot of times.
Note that his return value is:
#define SIG_ERR (void (*) ())-1
#define SIG_DFL (void (*) ()) 0
#define Sig_ign (void (*) ()) 1
Once said before, be sure to pay attention to the return value of the processing. Be sure to determine the return value of the function.
2. All wind messages can be intercepted, but under Linux, Sigstop,sigkill signals cannot be intercepted. Keeping these two signals is not intercepted so that the system, the user, can directly kill any process (of course, the process of authorization to kill).
3. System functions can be interrupted by signals.
Advanced Programming writes this:
When a process catches a signal and continues execution, it first executes the instructions in that signal handler. If you return from a signal handler (for example, if you do not call E x i t or l o n g J M P), you continue to perform the normal sequence of instructions that the process is executing when the signal is caught (this is similar to what was done when a hardware interrupt occurred). In a signal handler, however, it is not possible to determine where the process executes when the signal is captured.
In other words, the system does not give you the stack environment at that time, jump out of the system function that is executing directly. This is different from the processing of hard interrupts (the interruption of the environment, the execution of interrupt code, and the Interruption of environmental recovery).
For example, in the process of sleep (60), the process receives a signal. This signal interrupts the execution of this function, that is, not having enough sleep, sleeping for 20 seconds, and coming out in 30 seconds. The consequences are a little bit smaller, you think, if you write in the process of writing a half is interrupted, what will happen.
Our common approach to this matter is:
1. Block out unwanted or all signals.
sigset_t sets;//an empty Sigset collection.
Sigfillset (&sets);/fill all the signals.
Sigprocmask (Sig_block, &sets, 0);
By the way, one of the parameters of Sigprocmask is introduced. It is necessary to note that the process has a collection of current blocking signals. The operation on the collection.
Sig_block:
The resulting set shall is the Union of the current set and the signal set pointed to by set.
Sig_setmask:
The resulting set shall is the signal set pointed to by set.
Sig_unblock
The resulting set shall be the intersection of the "current set" and the complement of the signal set pointed to by set.
All the signals are blocked, then how to use the signal to let the program exit normally. Linux is no more than Windows has a close button to let you press. Most programs have to use the signal to get the program to quit normally, and not to kill the program directly, because the normal exit process usually needs to do a part (such as cleaning, etc.) work. At this point, you can block the program from waiting for a blocked signal, usually sigterm. A bit like the close message inside windows.
while (Sigwaitinfo (&sets, 0)!= sigterm);
The sigterm signal is coming, the program is ready to exit. Oh.
The second parameter is the SIG info, which is not set to null. If you use it, look for help yourself.
Sigtimedwait just added a time parameter. However, the timeout under Linux is not the same as the one below win. His timeout is in contrast to the present time. Below is a function I wrote. The time struct TIMESPEC structure used to get the timeout.
int gettimeout (int sec,long nsec,struct timespec& abstimeout)
{
struct Timeval now;
Gettimeofday (&now, 0);
Abstimeout.tv_sec = now.tv_sec + sec;
Abstimeout.tv_nsec = (NOW.TV_USEC * 1000) + nsec;
if (abstimeout.tv_nsec >= 1000000000)
{
abstimeout.tv_sec++;
Abstimeout.tv_nsec-= 1000000000;
}
return 0;
}
Generally there is this need for the program, are in the main thread inside the shield all signals, and then, in another thread inside blocking wait for a signal. Then, the function of other threads inherits the signal shielding method inside the main thread, shielding all signals. However, when debugging with GDB, GDB generated the signal, using these methods can not be stopped. This method can only stop the signal sent by the system.
2. The return value is processed. "Manual" Support for this soft interrupt.
Perform application-level processing on functions that may be interrupted, such as:
while (:: Close (FD) = = 1 && errno = = eintr);
Sleep is interrupted, returning the number of seconds remaining. Write returns the number of bytes that have been correctly written. Wait a minute. Using this information, you can do a function back, just write more trouble.
It should be noted that in Linux, system functions are divided into reentrant and inaccessible. The principle of distinction is whether this function changes the global data structure. That is, before the function is reentrant, it is important to consider changes to the global data structure at the time of the last entry. That is, if necessary, do some environmental preservation and recovery. Like what:
Advanced programming is written like this:
To understand that even the functions listed in table 1 0-3 are invoked in a signal handler, because each process has only one E R r n variable, we may have modified its original value. Consider a signal handler that is called just after the M a i n is set to E R r N O. If the signal handler calls R e a D, it may change the value of e R r N O, replacing the value just set by M a i n. Therefore, as a general rule, when the functions listed in table 1 0-3 are invoked in a signal handler, they should be saved before they are restored to errno.
Also note that Sigaction has a parameter inside it, Sig_restart. What he means is that when a function is interrupted by a signal, the system can automatically recall the function again. And some versions do not support this parameter.
Try to imagine what happens when your write function is called again with the same parameters.
In advanced programming, that's what it says:
P O S I X. 1 allows for a system call to be implemented again, but this is not required. System V's default mode of operation is to no longer start system calls. But s V R 4 uses S i g a c t i o n (see 1 0. 1 4), you can specify a Sa_restart selection to start a system call that is interrupted by the signal. In the 4. In 3 + B S D, the reset of the system call depends on which function is invoked to set the signal processing configuration. Early with the 4. The 3 B S D-compatible s I g v e C function causes the system calls that are interrupted by this signal to automatically start again. However, use newer with POSIX. 1 compliant sigaction do not cause them to start again. However, as in S V R 4, you can use the Sa_restart option in sigaction to cause the kernel to again start a system call that is interrupted by that signal.
Under Windows, you don't have to worry about messages interrupting system calls. However, it is also possible to assume that the loss is a quick response to a soft interrupt signal.
Two. Several special signals
1. Sigpipe:
under Linux to write the socket program, if you try to send to a disconnected socket, it will let the bottom throw a sigpipe signal.
The default processing for this signal is to exit the process, which is not what we expect most of the time. Therefore, we need to overload this signal processing method. The following code is invoked to safely shield Sigpipe:
struct sigaction sa;
Sa.sa_handler = sig_ign;
sigaction (sigpipe, &sa, 0);
Think of these lines of code as WSAStartup () under Windows.