linux的signal生成与deliver的理解。
要理解,当然要从数据结构去理解以下代码来自<linux/sched.h> <asm-generic/signal.h> <linux/signal.h>。
每一个process的task descriptor task_struct中跟signal有关的field:
task_struct{
....
struct signal_struct *signal;
struct sighand_struct *sighand;
struct sigpending pending; //private pending signal for every LWP
sigset_t blocked, real_blocked;
....
}
struct sigpending{
struct list_head list;
sigset_t signal; //32位或者64位,每一位对应一个signal类型。
}
struct signal_struct *signal; //存储了shared signal pending
struct signal_struct{
....
struct sigpending pending; //shared signal pending
....
}
struct sighand_struct *sighand;
struct sighand_struct { //当信号到来的时候,需要调用signal_handler进行处理。
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
wait_queue_head_t signalfd_wqh;
};
简易对signal的理解:
signal的作用:
1 进程间通信。比如说kill,如果权限足够,那么就会给对应的进程发送kill相关信号。下面具体研究各个信号是干什么用的。
2 将中断以signal的形式反应给应用程序,并进行相应的操作。
signal的实现:
现在假设是sigset_t 为32位的类型,并且一般的话,系统中也定义了32中signal类型,一个类型对应一位。
1 signal generation
signal generation是相对于signal deliver来说的。
具体的动作为:
- 现在来了一个信号,首先task_struct中sigset_t blocked.没有将当前这个信号block住。
- 目标进程如果不正在运行,signal就会被放到pending中。
- 当kernel调度进程运行的时候,即是从Kernel mode转向User mode的时候,检查被pending的signal,并调用相应的signal-handler进行处理。
附上Understanding the linux kernel对信号的总结,下面全是经典:
/* Importent
At any time pending signal of a given type may exist for a process; additional pending signals of the same type to the same process
are not queued but simply discarded.
In general, a signal may remain pending for an unpredictable amount of time. The following factors must be
taken into consideration:
1 Signals are usually delivered only to the currently running process (that is, to the current process).
2 Signals of a given type may be selectively blocked by a process (see the later section "Modifying the
Set of Blocked Signals"). In this case, the process does not receive the signal until it removes the
block.
3 When a process executes a signal-handler function, it usually masks the corresponding signali.e., it
automatically blocks the signal until the handler terminates. A signal handler therefore cannot be
interrupted by another occurrence of the handled signal, and the function doesn't need to be reentrant.
Importent */
//底下稍微不重要
Although the notion of signals is intuitive, the kernel implementation is rather complex. The kernel must:
Remember which signals are blocked by each process. •
When switching from Kernel Mode to User Mode, check whether a signal for a process has arrived.
This happens at almost every timer interrupt (roughly every millisecond).
•
Determine whether the signal can be ignored. This happens when all of the following conditions are
fulfilled:
The destination process is not traced by another process (the PT_PTRACED flag in the
process descriptor ptrace field is equal to 0).
[*]
[*]
If a process receives a signal while it is being traced, the kernel stops the
process and notifies the tracing process by sending a SIGCHLD signal to it.
The tracing process may, in turn, resume execution of the traced process by
means of a SIGCONT signal.
♦
The signal is not blocked by the destination process. ♦
The signal is being ignored by the destination process (either because the process explicitly
ignored it or because the process did not change the default action of the signal and that
action is "ignore").
♦
•
Handle the signal, which may require switching the process to a handler function at any point during
its execution and restoring the original execution context after the function returns.
对Signal的类型的总结,等到使用到的时候,自然而然了解它们的作用了:
Standard Signals
Linux supports the standard signals listed below. Several signal numbers are architecture dependent, as indicated in the "Value" column. (Where three values are given, the first one is usually valid for alpha and sparc, the middle one for i386, ppc and sh, and the last one for mips. A - denotes that a signalis absent on the corresponding architecture.)
First the signalsdescribed in the original POSIX.1-1990 standard.
Signal | Value | Action | Comment |
SIGHUP | |||
or death of controlling process | |||
SIGINT | 2 | Term | Interrupt from keyboard |
SIGQUIT | 3 | Core | Quit from keyboard |
SIGILL | 4 | Core | Illegal Instruction |
SIGABRT | 6 | Core | Abort signal from abort(3) |
SIGFPE | 8 | Core | Floating point exception |
SIGKILL | 9 | Term | Kill signal |
SIGSEGV | 11 | Core | Invalid memory reference |
SIGPIPE | 13 | Term | Broken pipe: write to pipe with no readers |
SIGALRM | 14 | Term | Timer signal from alarm(2) |
SIGTERM | 15 | Term | Termination signal |
SIGUSR1 | 30,10,16 | Term | User-defined signal 1 |
SIGUSR2 | 31,12,17 | Term | User-defined signal 2 |
SIGCHLD | 20,17,18 | Ign | Child stopped or terminated |
SIGCONT | 19,18,25 | Cont | Continue if stopped |
SIGSTOP | 17,19,23 | Stop | Stop process |
SIGTSTP | 18,20,24 | Stop | Stop typed at tty |
SIGTTIN | 21,21,26 | Stop | tty input for background process |
SIGTTOU | 22,22,27 | Stop | tty output for background process |
The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
Next the signalsnot in the POSIX.1-1990 standard but described in SUSv2 and POSIX.1-2001.
Signal | Value | Action | Comment |
SIGBUS | |||
SIGPOLL | Term | Pollable event (Sys V). Synonym of SIGIO | |
SIGPROF | 27,27,29 | Term | Profiling timer expired |
SIGSYS | 12,-,12 | Core | Bad argument to routine (SVr4) |
SIGTRAP | 5 | Core | Trace/breakpoint trap |
SIGURG | 16,23,21 | Ign | Urgent condition on socket (4.2BSD) |
SIGVTALRM | 26,26,28 | Term | Virtual alarm clock (4.2BSD) |
SIGXCPU | 24,24,30 | Core | CPU time limit exceeded (4.2BSD) |
SIGXFSZ | 25,25,31 | Core | File size limit exceeded (4.2BSD) |
Up to and including Linux 2.2, the default behaviour for SIGSYS, SIGXCPU, SIGXFSZ, and (on architectures other than SPARC and MIPS) SIGBUS was to terminate the process (without a core dump). (On some other Unices the default action for SIGXCPU and SIGXFSZ is to terminate the process without a core dump.) Linux 2.4 conforms to the POSIX.1-2001 requirements for these signals, terminating the process with a core dump.
Next various other signals.
Signal | Value | Action | Comment |
SIGIOT | |||
SIGEMT | 7,-,7 | Term | |
SIGSTKFLT | -,16,- | Term | Stack fault on coprocessor (unused) |
SIGIO | 23,29,22 | Term | I/O now possible (4.2BSD) |
SIGCLD | -,-,18 | Ign | A synonym for SIGCHLD |
SIGPWR | 29,30,19 | Term | Power failure (System V) |
SIGINFO | 29,-,- | A synonym for SIGPWR | |
SIGLOST | -,-,- | Term | File lock lost |
SIGWINCH | 28,28,20 | Ign | Window resize signal (4.3BSD, Sun) |
SIGUNUSED | -,31,- | Term | Unused signal (will be SIGSYS) |
(Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a sparc.)
SIGEMT is not specified in POSIX.1-2001, but nevertheless appears on most other Unices, where its default action is typically to terminate the process with a core dump.
SIGPWR (which is not specified in POSIX.1-2001) is typically ignored by default on those other Unices where it appears.
SIGIO (which is not specified in POSIX.1-2001) is ignored by default on several other Unices.