Linux signal those things __linux

Source: Internet
Author: User
Tags sigint signal signal handler strlen

Linux signal Those things (1)

Http://blog.chinaunix.net/uid-24774106-id-4061386.html

Bean_lee

Linux programming, the signal is a love and hate and have to mention an area. Recently, I focused on the signal related content of Linux, sharing it, also to prevent myself from forgetting.
The nature of the signal is asynchronous. Asynchronous one of the word, listening to high-end atmospheric grade, and let people cloud mountain fog around, it is not. In fact, we think that our world is asynchronous, everyone doing things, not always a->b->c->d this. For example, I bought something online, I actually do not know when the courier can arrive. I may be in the company, in the water, in the back of the mail, in the search for bugs, in writing code, suddenly received the call of small brother, note that this is the signal delivery. Due to the arrival of the courier, I had to stop my work at hand, to sign Express. This is the typical asynchronous in legend. I do not know when the delivery of small brother call me, but I received the phone to sign, this is my signal processing function. More advanced, if I am attending an important meeting, I may need to block the call of the Express brother (if I know its phone), this is already the advanced application of the Linux signal (sigprocmask).
A signal is a mechanism that simulates the interrupt mechanism at the software level, and the kernel makes a process aware of a particular event. Force the process to perform the corresponding signal processing function. As for the source of the signal may come from hardware such as pressing the keyboard or hardware failure (such as CTRL + C to send SIGINT), may come from other processes (Kill,sigqueue), may be from their own process (raise).
The essence of a signal is a communication between processes, in which a process can send a signal to another process, at least passing the int value of Signo. In fact, the content of the communication can be far more than Signo, you can use the SA_SIGINFO flag bit to notify the process to get additional information.
I hate soup words son, but the above a big tuo soup words son, but really really said the nature of the signal.
As mentioned earlier, signal is a love-hate feature, because of heavy historical baggage. I'm going to go one by one ways.
In the ancient times, Unix had signal this feature, but there were several problems with signal:
1 traditional signal processing functions are one-off, not permanent.
Linux is still implementing this flawed signal system call for backward compatibility. You can see that the kernel code in the signal system call has sa_oneshot this flag bit.
#ifdef __arch_want_sys_signal
/*
* For backwards compatibility. Functionality superseded by Sigaction.
*/
Syscall_define2 (Signal,int, SIG, __sighandler_t, Handler)
{
struct k_sigaction New_sa, Old_sa;
int ret;

New_sa.sa.sa_handler= handler;
new_sa.sa.sa_flags= Sa_oneshot | Sa_nomask;
Sigemptyset (&new_sa.sa.sa_mask);

ret = Do_sigaction (sig, &new_sa, &old_sa);

return ret? RET:(unsigned long) Old_sa.sa.sa_handler;
}
#endif/* __arch_want_sys_signal*/

This sa_oneshot sign is equivalent to the Sa_resethand logo: in arch/x86/include/uapi/asm/signal.h:
#define Sa_oneshot Sa_resethand

Signal generation, to the signal processing function to start execution, there must be a time lag. The kernel begins to force the process to respond to the signal, which is called signal delivery. That is, the signal is generated, the kernel is only recorded in the process descriptor, the process received a signal X, and did not immediately force the process to respond to the signal. Signals that have been generated but not yet passed are called hang signals. For non-real time, the signal is not queued, bitmap occupies a bit. In the case of a real-time signal, the line is queued and the same signal may have multiple pending signals. This is not much to say, later naturally mentioned.

The diagram above reflects how the kernel transmits signals. The basic is to select a hang signal, and then process a signal. Get_signal_to_deliver is the process of selecting a signal to handle. Code in KERNEL/SIGNAL.C, which has the following codes:
if (ka->sa.sa_handler== sig_ign) * do nothing.*/
Continue
if (ka->sa.sa_handler!= SIG_DFL) {
* Run the handler.*/
*return_ka = *ka;

if (ka->sa.sa_flags& sa_oneshot)
Ka->sa.sa_handler= SIG_DFL;

Break * would return Non-zero "SIGNR" Value * * *
}

We see that Linux also implements the signal of this defective system call. The traditional signal system call, his signal processing function is one-time, after the execution, the signal processing function becomes SIG_DFL.
It is worth mentioning that the glibc signal function, the call is not the traditional signal system calls, but rt_sigaction system calls, this one-time defect has been resolved. How to prove:
manu@manu-hacks:~/code/c/self/signal$ Cat signal_fault_1.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>

#define MSG "OMG, I catch the signal sigint\n"
#define MSG_END "ok,finished process signal sigint\n"
int Do_heavy_work ()
{
int i;
int k;
Srand (Time (NULL));

for (i= 0; i < 100000000;i++)
{
K = rand ()%1234589;
}

}

void Signal_handler (int signo)
{
Write (2,msg,strlen (MSG));
Do_heavy_work ();
Write (2,msg_end,strlen (msg_end));
}

int main ()
{
Char input[1024]= {0};

#if defined Traditional_signal_api
if (Syscall (sys_signal, sigint,signal_handler) = = 1)
#elif defined Systemv_signal_api
if (sysv_signal (sigint,signal_handler) = =-1)
#else
if (signal (sigint,signal_handler) = = Sig_err)
#endif

{
fprintf (stderr, "signal failed\n");
return-1;
}

printf ("Input a string:\n");
if (fgets (input,sizeof (input), stdin) ==null)
{
fprintf (stderr, "Fgets failed (%s) \ n", Strerror (errno));
Return-2;
}
Else
{
printf ("You entered:%s", input);
}

return 0;


}

When compiling, I do not define SYSTEMV_SIGNAL_API, is the standard glibc SIGNAL function, I use Strace trace glibc function Call of the SIGNAL functions are:
Rt_sigaction (SIGINT, {0x8048736,[int], Sa_restart}, {sig_dfl,[], 0}, 8) = 0

    Test results are as follows:
manu@manu-hacks:~/code/c/self/signal$ gcc-o signal_glibc signal_fault_1.c
MANU@MANU-HACKS:~/CODE/C/SELF/SIGNAL$./SIGNAL_GLIBC
Input A string:
Input^comg, I catch the signal SIGINT
^c ok,finished process Signal SIGINT
OMG, I catch the signal SIGINT
ok,finished process signal SIGINT
^COMG, I Catch the signal SIGINT
ok,finished process signal SIGINT
^COMG, I catch the signal SIGINT
ok,finished proces S signal SIGINT
^z
[1]+ stopped./signal_glibc

The Signal processing function we install is not one-off, because the function called by the GLIBC signal function is not a signal system call, and there is no sa_oneshot flag bit.
How we experience the old SIGNAL,GLIBC provides a sysv_signal interface, as described in manual:
However sysv_signal () provides the System V unreliable signal semantics, that is:a) the disposition of the sig‐
NAL is reset to the default then the handler is invoked; b) deliveryof further instances of the signal is not
Blocked while the signal handler is Executing;and c) if the handler interrupts (certain) blocking system calls,
Then the system call isn't automatically restarted.

For our example, we only need to:
Gcc-dsystemv_signal_api-o Signal_sysv signal_fault_1.c

Let's look at the following:
Manu@manu-hacks:~/code/c/self/signal$./signal_sysv
Input a string:
^COMG, I catch the signal SIGINT
^c
manu@manu-hacks:~/code/c/self/signal$ Mans sysv_signal

The second CTRL + C led to the introduction of the process, because sysv_signal this traditional signal installation function is one-time. Strace also proves this point:
Rt_sigaction (SIGINT, {0x8048756,[], Sa_interrupt|sa_nodefer|sa_resethand}, {SIG_DFL, [], 0}, 8) = 0

Do you remember:
#define Sa_oneshot Sa_resethand

Instead of signal system calls, we found that SysV called rt_sigaction system calls. If you have to taste the traditional signal system call, it is not difficult.
Gcc-dtraditional_signal_api-o signal_traditional signal_fault_1.c

We found that the signal processing function of the second SIGINT signal has been SIG_DFL, so that the process exits.
Manu@manu-hacks:~/code/c/self/signal$./signal_traditional
Input a string:
^COMG, I catch the signal SIGINT
^c

We can prove by Strace that we did call the signal system call:
Signal (SIGINT, 0x8048736) = 0 (SIG_DFL)

2 early signals, no shielding is being processed by the signal.
How to prove this point. In my example, I deliberately do a very heavy and time-consuming operation in the signal processing function, which makes it easy to create a scene when the signal a is processed and another signal a is deliver.
Because Do_heavy_work is a time-consuming operation, signal processing completes the process of processing the completed statement on the standard error, which characterizes the end of signal processing.
Let's look at the traditional signal, receiving a SIGINT signal:
Manu@manu-hacks:~/code/c/self/signal$./signal_traditional
Input a string:
^COMG, I catch the signal SIGINT
ok,finished Process Signal SIGINT
Fgets failed (interrupted system call)
manu@manu-hacks:~/code/c/self/signal$

If I send a SIGINT again when the process processes the signal processing function, this SIGINT may also be deliver by the kernel. Then the signal processing function is interrupted,
Manu@manu-hacks:~/code/c/self/signal$./signal_traditional
Input a string:
^COMG, I catch the signal SIGINT
^c
manu@manu-hacks:~/code/c/self/signal$

    We saw that we received the I catch the signal SIGINT print, however, and did not receive ok,i finished process signal SIGINT, This suggests that the traditional signal does not mask the signal being processed.
    So what about the signal function of our current glibc.
    Strace to help again?

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.