实时信号和非实时信号Word下载.docx
- 文档编号:4053840
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:47
- 大小:37.30KB
实时信号和非实时信号Word下载.docx
《实时信号和非实时信号Word下载.docx》由会员分享,可在线阅读,更多相关《实时信号和非实时信号Word下载.docx(47页珍藏版)》请在冰点文库上搜索。
oldmask,NULL);
return0;
}
voidsig_handler(intsignum,siginfo_t*info,void*myact)
if(signum==SIGINT)
Gotacommonsignal\n"
else
Gotarealtimesignal\n"
将程序编译好之后,再开一个终端用于发送实时信号。
ecy@ecy-geek:
~/pthreads$./sigqueue_receive
pid=8871
进程开始睡眠……
在新的终端输入:
~/pthreads$kill-SIGRTMIN8871
连续发送四个SIGRTMIN,接着回到之前的终端,连续四次按下"
ctrl+c"
。
^C^C^C^C
最后进程终于醒来,整个输出如下:
^C^C^C^CGotarealtimesignal
Gotarealtimesignal
Gotacommonsignal
果然接受到四个实时信号,并且四次调用了信号处理函数,而对于SIGINT,虽然也按下了四次"
,但是进程对其只做一次处理。
我发现这儿有个细节有点意思,这个例子中是先发实时信号后发非实时信号,所以信号处理函数先处理实时信号,如果只是按照顺序注册信号的话,这很好理解,但是换一下,先按下了四次"
然后使用kill发四次实时信号,结果发现输出的结果仍然一样,这就有点怪了,这说明实时信号的优先级比非实时信号要高,内核每个进程的信号组成一个双向链表,实时信号插入的时候就不是随便插在尾部了。
哎,不懂内核什么都要靠猜测,不爽~~在网上找到这样一段话:
信号的优先级:
信号实质上是软中断,中断有优先级,信号也有优先级。
如果一个进程有多个未决信号,则对于同一个未决的实时信号,内核将按照发送的顺序来递送信号。
如果存在多个未决的实时信号,则值(或者说编号)越小的越先被递送。
如果既存在不可靠信号,又存在可靠信号(实时信号),虽然POSIX对这一情况没有明确规定,但Linux系统和大多数遵循POSIX标准的操作系统一样,将优先递送不可靠信号。
经过我反反复复地试验,我发现实验结果和上面描述的刚好相反,信号的编号越大越先被递送,一个进程如果处理SIGQUIT(3),SIGINT
(2),SIGHUP
(1)(通过"
kill-l"
可以查看信号的编号),那么先后给该进程发送SIGINT,SIGHUP,SIGQUIT,处理的顺序会是SIGQUIT,SIGINT,SIGHUP,不论改变这个三个信号的发送顺序,处理的顺序都是一样的。
信号详解
博客分类:
∙linux
linuxsignal
一信号的种类
可靠信号与不可靠信号,实时信号与非实时信号
可靠信号就是实时信号,那些从UNIX系统继承过来的信号都是非可靠信号,表现在信号
不支持排队,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次.信号值小于
SIGRTMIN的都是非可靠信号.
非可靠信号就是非实时信号,后来,Linux改进了信号机制,增加了32种新的信号,这些信
号都是可靠信号,表现在信号支持排队,不会丢失,发多少次,就可以收到多少次.信号值
位于[SIGRTMIN,SIGRTMAX]
区间的都是可靠信号.
关于可靠信号,还可以参考WIKI的一段话:
Text代码
1.The
real-time
signals,
ranging
from
SIGRTMIN
to
SIGRTMAX,
are
a
set
of
signals
that
can
be
used
for
application-defined
purposes.
2.Because
may
have
different
values
on
Unix-like
systems,
applications
should
always
refer
the
in
form
SIGRTMIN+n,
where
n
is
constant
integer
expression.
3.The
number
properties
differentiate
them
other
and
make
suitable
purposes:
4.*
Multiple
instances
signal
sent
process
all
will
delivered.
5.*
Real-time
accompanied
by
an
or
pointer
value
(see
sigqueue[2]).
6.*
guaranteed
delivered
order
they
were
emitted.
Thereal-timesignals,rangingfromSIGRTMINtoSIGRTMAX,areasetofsignalsthatcanbeusedforapplication-definedpurposes.
BecauseSIGRTMINmayhavedifferentvaluesondifferentUnix-likesystems,applicationsshouldalwaysrefertothesignalsintheformSIGRTMIN+n,wherenisaconstantintegerexpression.
Thereal-timesignalshaveanumberofpropertiesthatdifferentiatethemfromothersignalsandmakethemsuitableforapplication-definedpurposes:
*Multipleinstancesofareal-timesignalcanbesenttoaprocessandallwillbedelivered.
*Real-timesignalscanbeaccompaniedbyanintegerorpointervalue(seesigqueue[2]).
*Real-timesignalsareguaranteedtobedeliveredintheordertheywereemitted.
命令行输入kill-l,可以列出系统支持的所有信号:
C代码
1.~>
kill
-l
2.
1)
SIGHUP
2)
SIGINT
3)
SIGQUIT
4)
SIGILL
5)
SIGTRAP
3.
6)
SIGABRT
7)
SIGBUS
8)
SIGFPE
9)
SIGKILL
10)
SIGUSR1
4.11)
SIGSEGV
12)
SIGUSR2
13)
SIGPIPE
14)
SIGALRM
15)
SIGTERM
5.16)
SIGSTKFLT
17)
SIGCHLD
18)
SIGCONT
19)
SIGSTOP
20)
SIGTSTP
6.21)
SIGTTIN
22)
SIGTTOU
23)
SIGURG
24)
SIGXCPU
25)
SIGXFSZ
7.26)
SIGVTALRM
27)
SIGPROF
28)
SIGWINCH
29)
SIGIO
30)
SIGPWR
8.31)
SIGSYS
34)
35)
SIGRTMIN+1
36)
SIGRTMIN+2
37)
SIGRTMIN+3
9.38)
SIGRTMIN+4
39)
SIGRTMIN+5
40)
SIGRTMIN+6
41)
SIGRTMIN+7
42)
SIGRTMIN+8
10.43)
SIGRTMIN+9
44)
SIGRTMIN+10
45)
SIGRTMIN+11
46)
SIGRTMIN+12
47)
SIGRTMIN+13
11.48)
SIGRTMIN+14
49)
SIGRTMIN+15
50)
SIGRTMAX-14
51)
SIGRTMAX-13
52)
SIGRTMAX-12
12.53)
SIGRTMAX-11
54)
SIGRTMAX-10
55)
SIGRTMAX-9
56)
SIGRTMAX-8
57)
SIGRTMAX-7
13.58)
SIGRTMAX-6
59)
SIGRTMAX-5
60)
SIGRTMAX-4
61)
SIGRTMAX-3
62)
SIGRTMAX-2
14.63)
SIGRTMAX-1
64)
SIGRTMAX
~>
kill-l
1)SIGHUP2)SIGINT3)SIGQUIT4)SIGILL5)SIGTRAP
6)SIGABRT7)SIGBUS8)SIGFPE9)SIGKILL10)SIGUSR1
11)SIGSEGV12)SIGUSR213)SIGPIPE14)SIGALRM15)SIGTERM
16)SIGSTKFLT17)SIGCHLD18)SIGCONT19)SIGSTOP20)SIGTSTP
21)SIGTTIN22)SIGTTOU23)SIGURG24)SIGXCPU25)SIGXFSZ
26)SIGVTALRM27)SIGPROF28)SIGWINCH29)SIGIO30)SIGPWR
31)SIGSYS34)SIGRTMIN35)SIGRTMIN+136)SIGRTMIN+237)SIGRTMIN+3
38)SIGRTMIN+439)SIGRTMIN+540)SIGRTMIN+641)SIGRTMIN+742)SIGRTMIN+8
43)SIGRTMIN+944)SIGRTMIN+1045)SIGRTMIN+1146)SIGRTMIN+1247)SIGRTMIN+13
48)SIGRTMIN+1449)SIGRTMIN+1550)SIGRTMAX-1451)SIGRTMAX-1352)SIGRTMAX-12
53)SIGRTMAX-1154)SIGRTMAX-1055)SIGRTMAX-956)SIGRTMAX-857)SIGRTMAX-7
58)SIGRTMAX-659)SIGRTMAX-560)SIGRTMAX-461)SIGRTMAX-362)SIGRTMAX-2
63)SIGRTMAX-164)SIGRTMAX
非可靠信号一般都有确定的用途及含义,
可靠信号则可以让用户自定义使用
二信号的安装
早期的Linux使用系统调用signal来安装信号
void(*signal(intsignum,void(*handler))(int)))(int);
该函数有两个参数,signum指定要安装的信号,handler指定信号的处理函数.
该函数的返回值是一个函数指针,指向上次安装的handler
经典安装方式:
if(signal(SIGINT,SIG_IGN)!
=SIG_IGN){
signal(SIGINT,sig_handler);
先获得上次的handler,如果不是忽略信号,就安装此信号的handler
由于信号被交付后,系统自动的重置handler为默认动作,为了使信号在handler
处理期间,仍能对后继信号做出反应,往往在handler的第一条语句再次调用signal
sig_handler(ingsignum)
/*重新安装信号*/
signal(signum,sig_handler);
......
我们知道在程序的任意执行点上,信号随时可能发生,如果信号在sig_handler重新安装
信号之前产生,这次信号就会执行默认动作,而不是sig_handler.这种问题是不可预料的.
使用库函数sigaction
来安装信号
为了克服非可靠信号并同一SVR4和BSD之间的差异,产生了POSIX信号安装方式,使用
sigaction安装信号的动作后,该动作就一直保持,直到另一次调用sigaction建立另一个
动作为止.这就克服了古老的signal调用存在的问题
intsigaction(intsignum,conststructsigaction*act,structsigaction*oldact));
structsigactionaction,old_action;
/*设置SIGINT*/
action.sa_handler=sig_handler;
sigemptyset(&
action.sa_mask);
sigaddset(&
action.sa_mask,SIGTERM);
action.sa_flags=0;
/*获取上次的handler,如果不是忽略动作,则安装信号*/
sigaction(SIGINT,NULL,&
old_action);
if(old_action.sa_handler!
sigaction(SIGINT,&
action,NULL);
基于sigaction实现的库函数:
signal
sigaction自然强大,但安装信号很繁琐,
目前linux中的signal()是通过sigation()函数
实现的,因此,即使通过signal()安装的信号,在信号处理函数的结尾也不必
再调用一次信号安装函数。
三如何屏蔽信号
所谓屏蔽,并不是禁止递送信号,而是暂时阻塞信号的递送,
解除屏蔽后,信号将被递送,不会丢失.相关API为
intsigemptyset(sigset_t*set);
intsigfillset(sigset_t*set);
intsigaddset(sigset_t*set,intsignum);
intsigdelset(sigset_t*set,intsignum);
intsigismember(constsigset_t*set,intsignum);
intsigsuspend(constsigset_t*mask);
intsigpending(sigset_t*set);
-----------------------------------------------------------------
int
sigprocmask(int
how,
const
sigset_t*set,sigset_t*oldset));
sigprocmask()函数能够根据参数how来实现对信号集的操作,操作主要有三种:
*SIG_BLOCK在进程当前阻塞信号集中添加set指向信号集中的信号
*SIG_UNBLOCK如果进程阻塞信号集中包含set指向信号集中的信号,则解除
对该信号的阻塞
*SIG_SETMASK更新进程阻塞信号集为set指向的信号集
屏蔽整个进程的信号:
1.#include
<
2.#include
3.#include
stdlib.h>
4.#include
error.h>
5.#include
6.
7.void
sig_handler(int
signum)
8.{
9.
printf("
catch
SIGINT\n"
10.}
11.
12.int
main(int
argc,
char
**argv)
13.{
14.
sigset_t
block;
15.
struct
sigaction
action,
old_action;
16.
17.
/*
安装信号
*/
18.
action.sa_handler
=
sig_handler;
19.
20.
action.sa_flags
0;
21.
22.
sigaction(SIGINT,
NULL,
&
23.
if
(old_action.sa_handler
!
SIG_IGN)
{
24.
NULL);
25.
}
26.
27.
屏蔽信号
28.
block);
29.
block,
SIGINT);
30.
31.
block
32.
sigprocmask(SIG_BLOCK,
33.
34.
-->
send
\n"
35.
kill(getpid(),
36.
37.
38.
sleep
(1);
39.
40.
解除信号后,
之前触发的信号将被递送,
41.
*
但SIGINT是非可靠信号,
只会递送一次
42.
43.
unblock
44.
sigprocmask(SIG_UNBLOCK,
45.
46.
sleep
(2);
47.
48.
return
49.}
voidsig_handler(intsignum)
catchSIGINT\n"
intmain(intargc,char**argv)
sigset_tbloc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实时 信号
![提示](https://static.bingdoc.com/images/bang_tan.gif)