51Testing软件测试网mNmR
l
n 51Testing软件测试网
QS8Ha2vO(d
51Testing软件测试网$U5?&Xpl,K!O$e第10章 信号51Testing软件测试网j$]9E4A:F4z
51Testing软件测试网rJ ?v-E0wh_y.i
1n?^0mz`#O3I010.1 引言51Testing软件测试网Rc b
ak({k_y
信号是软件中断。它提供了一种处理异步事件的方法。51Testing软件测试网
Y4nTn2Qbq"d
51Testing软件测试网.a.g/}GG$P;B.]10.2 信号的概念51Testing软件测试网5|^4j{1M8{"m t
字符SIG开头 头文件<signal.h>中
"J:A|Z0r)]T0产生一个信号的条件:51Testing软件测试网/{D#MZCth!`
1.用户按某些终端键
0|7f%w#gNd02.硬件异常产生信号51Testing软件测试网^"ZEY`pcK5b&j#YZ
3.进程用kill(2)函数可将信号发送给令一个进程或进程组
wx)t |6W*N `04.用户可用kill(1)命令将信号发送给其他进程
5`-p QBq!Co6G05.当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号
Lzv
Q+ct/r+k[051Testing软件测试网lxkS-_!Gy信号出现时的三种操作方式:
s(g$C8ep01.忽略此信号
^2y w'q0x`rx02.捕捉信号
bY,s/n?7R03.执行系统默认动作51Testing软件测试网M#X`KH[G1i+D7u_
]E$Z2Zxw0表10-1 UNIX信号
]5K(G`'~xX7P0r"pbQ]n@1l+y010.3 signal函数
'}AT2cl1C0signal函数为信号处理程序(signal handler)或信号捕捉函数(signal-catching function)
2I'Z}2}ig{0K0————————————————————————————————————————————————————
d A6}/Xy;M0#include <signal.h>
X:_
XMdVQ6Lkk0void (*signal(int signo,void (*func)(int)))(int);51Testing软件测试网_x3q!Q\D3??%y.|O
S
返回:成功则为以前的信号处理配置,若出错则为SIG_ERR
:E4{.\.{$^0————————————————————————————————————————————————————51Testing软件测试网!j ej;Q-BL6IL'@
51Testing软件测试网 V__h*]5F10.4 不可靠的信号
S e N
Qr/N010.5 中断的系统调用
bK)L7Yzz'R {v#S0系统调用分为两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用。
"O)X6G/F l{m051Testing软件测试网
RZ%N#\a d
r0D表10-2 几种信号实现所提供的功能
[&j.fU(}0 vQ ~:?4V-mV(c010.6 可再入函数
[:z+mJ@
j(D0进程捕捉到信号并继续执行时,首先执行该信号处理程序中的指令。如果从信号处理程序返回,则继续执行在捕捉到信号时进程正在执行的正常指令序列。51Testing软件测试网 LsH.h4aB0a&|+]'J?
如果进程正在执行某函数,由于捕捉到信号插入执行信号处理程序,其中又调用该函数,则可能会出错。所以引入了可再入函数的概念。
E*gq9S;D4jl051Testing软件测试网%y ? hz_#yNTI表10-3 信号处理程序中可以调用的可再入函数51Testing软件测试网i/g,J3U-x
b*a2YM3NX"Y:c9W010.7 SIGCLD语义
9x7M T%^N D!Q0SIGCLD是系统V的一个信号名,它不同于其他信号。如果用signal或sigset设置信号配置,则SVR4存在兼容性限制。所以务必了解你所用的系统中SIGCHLD信号的语义。51Testing软件测试网:?1e"CD'I*Kz
i1[n
51Testing软件测试网f&m9Nk0DdY-T10.8 可靠信号术语和语义
q s&kYW9@+u0当造成信号的事件发生时,为进程产生一个信号,内核在进程表中设置一个标志,这个动作称之为向一个进程递送了一个信号。在信号产生(generation)和递送(delivery)之间的时间间隔内,称信号未决(pending)。
Y&vT.| y/u%sx0当递送一个原来北阻塞的信号给进程时,而不是在产生该信号时,内核才决定对它的处理方式。于是进程在信号递送给它之前仍可改变对它的动作。
7\A T]Js051Testing软件测试网0{.D@&JoTt10.9 kill 和raise函数
vb4f$AhP0kill函数将信号发送给进程或进程组。raise函数则允许进程向自身发送信号。51Testing软件测试网%`5q!s*n%S
a,}kW
———————————————————————————————————————————————————51Testing软件测试网;k+M'?iD
#include <sys/ttpes.h>51Testing软件测试网5Ml^'O.f
#include <signal.h>
T/M+KBd-{b051Testing软件测试网
@XsIe.h
ad8J1RF`$Fint kill(pid_t pid,int signo);51Testing软件测试网 eX
MP
P{g
int raise(int signo);
0?T2a6i~2B)Gu0 两个函数返回:若成功则为0,若出错则为-151Testing软件测试网zh4[*o LQd
———————————————————————————————————————————————————
#r@8}+b*V0进程将信号发送给其他进程需要许可权。
l$w*g|o [F6rs0Z!jZ
[,fe3ot;^010.10 alarm和 pause函数51Testing软件测试网6v;s,l Bg[+Il
alarm函数可以设置一个时间值(闹钟时间),当所设置的时间值被超过后,产生SIGALRM信号。
E2~_ fzt
l0————————————————————————————————————————————————————51Testing软件测试网:{!C;j#V_"qIz)h
#include <unistd.h>
:TiKSKJ0aNWLD2W`6c0unsigned int alarm(unsigned int seconds);51Testing软件测试网U qV)r|r7h?
返回:0或以前设置的闹钟实践的余留秒数51Testing软件测试网-D8g| t^/p@
————————————————————————————————————————————————————
0l&c5Y{hR#pu0每个进程只能有一个闹钟时间。大多数是使用闹钟的进程捕捉此信号。
|
sh5Tq0pause函数使调用进程挂起直至捕捉到一个信号。51Testing软件测试网4k3k3w5u3i(dgi
————————————————————————————————————————————————————51Testing软件测试网F/xz%q]2Z8@
#include <unistd.h>
7l/SZO@C0int pause(void);51Testing软件测试网p-^{oz7v
返回:-1,errno设置为EINTR
B.Vf0WQi0————————————————————————————————————————————————————
{lsL$M0只有执行了一个信号处理程序并从其返回时,pause才返回。51Testing软件测试网1c TIm-R9LZ
51Testing软件测试网aV!V{.RI2~$l~3a10.11 信号集
O kpZh}"e#[J0能表示多个信号-信号集(signal set)的数据类型。51Testing软件测试网;|
k]$hZ{IXh
数据类型sigset_t包含一个信号集。五个处理信号集的函数:
B*H.a%hcsX'MV9Ls0————————————————————————————————————————————————————
].W ~'V8h%O`!T(j!j"]0#include <signal.h>
S:@A6?'Au~0int sigemptyset(sigset_t *set);51Testing软件测试网 qR)K,b5TL&dd$T
int sigfillset(sigset_t *set);51Testing软件测试网/q-]!bO A
nD
int sigaddset(sigset_t *set,int signo);
1_"z7NK*d3wMf0int sigdelset(sigset_t *set,int signo);
J Xc)} Adf0 四个函数返回:若成功则为0,若出错则为-1
J-N+x$UR8VQ0int sigismember(const sigset_t *set,int signo);
#nd rF&e!m[!x"\n ZN\0 返回:若真则为1,若假则为0
itltrJF,B'T1e0————————————————————————————————————————————————————51Testing软件测试网:tX0C Ij)d*Z
函数sigemptyset初始化由set指向的信号集,使排除其中所有信号。51Testing软件测试网7CX$H `(hO+~
函数sigfillset初始化由set指向的信号集,使其包括所有信号。
;cUu|,B0所有应用程序在使用信号集前,要对该信号集调用sigemptyset或sigfillset一次。
1o?-nz"uas0函数sigaddset将一个信号添加到现存集中,sigdelset则从信号集中删除一个信号。对所有以信号集作为参数的函数,都向其传送信号集地址。51Testing软件测试网O1hi:vV:]'OM
H9]
'@/O
n4F"VS$KA010.12 sigprocmask 函数51Testing软件测试网
a!~|3p{ l|+N*~
一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集。调用函数sigprocmask可以检测或更改(或两者)进程的信号屏蔽字。51Testing软件测试网#Q7m Uw/CtF9?O
————————————————————————————————————————51Testing软件测试网t5[!T"G u'Wg+bM
U
# include <signal.h>
1X7x.{4J@0D!B0int sigprocmask(int h o w, const sigset_t *s e t, sigset_t *o s e t) ;51Testing软件测试网;N4c b vF
返回:若成功则为0,若出错则为-1
3m!YhP2vg A-y$}%cWg{\0————————————————————————————————————————
)HUQF\0-i-I)kK+A010.13 sigpending函数51Testing软件测试网Jg!Bn
Zi
sigpending返回对于调用进程被阻塞不能递送和当前未决的信号集。该信号集通过set参数返回。51Testing软件测试网
lO2B5Lmy2Q
——————————————————————————————————————————51Testing软件测试网
mzmiU*dDbd:J;`X
#include <signal.h>
-iPsw |$T0int sigpending(sigset_t *s e t) ;51Testing软件测试网~w8X2Ao\
返回:若成功则为0,若出错则为-1
0w x;j/h
b})^ QU0——————————————————————————————————————————51Testing软件测试网X4y!j2oa(Jl7d
6p%~ ii_/Z010.14 sigaction函数
Y.VY!ks ?d n9b0sigaction函数的功能是检查或修改(或两者)与指定信号相关联的处理动作。此函数取代了UNIX早期版本使用的signal函数。51Testing软件测试网i'dU$D{5@
————————————————————————————————————51Testing软件测试网(Z:v'Wi5vj
#include <signal.h>
0[Wq~^0int sigaction(int signo, const struct sigaction *a c t,
J(_bTp/G0struct sigaction *oact) ;51Testing软件测试网SMQp_|,K
返回:若成功则为0,若出错则为- 1
5i9\
Iz0R^X0————————————————————————————————————
FM{.] ns!S0struct sigaction {
N.F]Ma$m0void (*sa_handler)(); /* addr of signal handler,51Testing软件测试网8OGU3S1u
yCt P{n
or SIG_IGN, or SIG_DFL */51Testing软件测试网6f)N(a@+xP1ag
sigset_t sa_mask; /* additional signals to block */
-q }mB4_v VU0int sa_flags; /* signal options, Table 10-5 */51Testing软件测试网3dW GT$Z
} ;51Testing软件测试网9f;ia_B
表10-5 信号处理的选择项标志( sa_flags)
7~-uN
i(]:LJ/xj0C!f|Z;v010.15 sigsetjmp 和siglongjmp函数51Testing软件测试网*LV.Z&l-v)HDB$m
在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。
UFCw!okYV7pT0POSIX.1定义了两个新函数sigsetjmp和siglongjmp。在信号处理程序中作非局部转移时应当使用这两个函数。
1`Z0g V.?7l|0——————————————————————————————————
t;HWF5KI wA0#include <setjmp.h>51Testing软件测试网,||%G ]uXU
E"p
int sigsetjmp(sigjmp_buf env, int savemask) ;
*`+rV[6R3S&z.Dz0返回:若直接调用则为0,若从siglongjmp调用返回则为非0
5Uw:c)ox6JgF0void siglongjmp(sigjmp_buf env, int val);51Testing软件测试网,s0@ K8L*EH-Nc:W
——————————————————————————————————
tM1Kb5LL `!F051Testing软件测试网:hxS`a2[10.16 sigsuspend函数
cb/O:BbG@0一个原子操作中实现恢复信号屏蔽字,然后使进程睡眠,这种功能是由sigsuspend函数所提供的。
{oDhM"u#] Kj.t}9H'|0——————————————————————————————————51Testing软件测试网e8Pj:gg5H
T
#include <signal.h>51Testing软件测试网j
{8X1M*s3@s
int sigsuspend(const sigset_t *sigmask) ;
!eK
pC{J7Y~s#M^0返回:-1, errno设置为EINTR51Testing软件测试网P0R
@+KD
——————————————————————————————————51Testing软件测试网:a&Hg+Vg+L4HT
51Testing软件测试网y%w$V%Jn.XUj;P10.17 abort函数51Testing软件测试网i1al.u0bO;h
abort函数的功能是使程序异常终止。
Q+zeOKF3\:j0——————————————————————————————————
z1d(x WX%_Xj0#include <stdlib.h>
i B7R5S{"Dp1]P @0void abort(void);
Z:C|*mApI&HG0此函数不返回
tu"i$iXmEz0——————————————————————————————————
7G.B-T9Ex#l0此函数将SIGABRT信号发送给调用进程。进程不应忽略此信号。
N/Ww}6^6]_6q+A0ANSI C要求若捕捉到此信号而且相应信号处理程序返回, abort仍不会返回到其调用者。
9~d:o?
\+t%x2U051Testing软件测试网7}c'K_{#oZ10.18 system 函数51Testing软件测试网,Bee[1jxuE
POSIX.2要求system忽略SIGINT和SIGQUIT,阻塞SIGCHLD。
G
O0lbm~*e^0因为由system执行的命令可能是交互作用命令,以及因为system的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system的调用者就不应接收这两个终端产生的信号。
~!_5TFw a/M6k0system的返回值是shell的终止状态,它不总是执行命令字符串进程的终止状态。51Testing软件测试网d `JC;@
51Testing软件测试网 i&K/X*L/u,c10.19 sleep函数51Testing软件测试网&s0Z?#_wV-^
——————————————————————————————————
9qw.~bS.{)G1yg0#include <unistd.h>51Testing软件测试网(Ty^Gx/RP%xN
unsigned int sleep(unsigned int seconds);
vsZ!T|4E_TO0返回:0或未睡的秒数
_qE&A-o
\F ^}i0R0——————————————————————————————————
$i3q4D7H7rD(s4u5v,m0此函数使调用进程被挂起直到:51Testing软件测试网 @k@[U;W
(1) 已经过了seconds所指定的墙上时钟时间,或者51Testing软件测试网o4Dy5he
(2) 该进程捕捉到一个信号并从信号处理程序返回。
wI7nF5q0sleep可以用alarm函数实现,但这并不是必需的。如果使用alarm,则这两个函数之间可以有交互作用。51Testing软件测试网-@0gt5[8D l4VH
51Testing软件测试网\J
S/B8hOO&{10.20 作业控制信号
h|,V8d#N{7HH0在表10-1中有六个POSIX.1认为是与作业控制有关的信号。
(x I!FPD&p8shd0SIGCHLD 子进程已停止或终止。51Testing软件测试网l+PO$yA2_#XCk.y~
SIGCONT 如果进程已停止,则使其继续运行。
(dj6C;f0Z
F T#t
i0SIGSTOP 停止信号(不能被捕捉或忽略)。51Testing软件测试网O)D:gnR7z2U8s0K A#A
SIGTSTP 交互停止信号。
0{)|4?*b-B0SIGTTIN 后台进程组的成员读控制终端。51Testing软件测试网nP'Op{_Kj5z-t
SIGTTOU 后台进程组的成员写控制终端。
)QA;_GE1]0大多数应用程序并不处理这些信号——交互式shell通常做处理这些信号的所有工作。
5U {0q W;~$E
\051Testing软件测试网4j\F"^_a~1gc10.21 其他特征
f6lkhmyO6{!HP0
N+['rA3`?G0