`
yzd
  • 浏览: 1816935 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

sigaction函数的详解

 
阅读更多
<div>
<span style="font-size: medium;">本文主要参考《unix环境高级编程》</span>
</div>
<div>
<span style="font-size: medium;"></span>
</div>
<div>
<span style="font-size: medium;">sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。</span>
</div>
<div>
<span style="font-size: medium;"></span>
</div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;"><span style="color: #0000ff;">int</span>
<span style="color: #ff0000;">sigaction</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">int</span>
signo<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
<span style="color: #0000ff;">struct</span>
<span style="color: #ff0000;">sigaction</span>
<span style="color: #0000cc;">*</span>
restrict act<span style="color: #0000cc;">,</span>
</span>
</code>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;"> <span style="color: #0000ff;">struct</span>
<span style="color: #ff0000;">sigaction</span>
<span style="color: #0000cc;">*</span>
restrict oact<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
</span>
</code>
</span>
</p>
</td>
</tr></tbody></table>
<p><span style="font-size: medium;">结构sigaction定义如下:</span>
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;"><span style="color: #0000ff;">struct</span>
<span style="color: #ff0000;">sigaction</span>
<span style="color: #0000cc;">{</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
sa_handler<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br>
sigset_t sa_mask<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
sa_flag<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
sa_sigaction<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">,</span>
siginfo_t <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000cc;">;</span>
</span>
</code>
</span>
</p>
</td>
</tr></tbody></table>
<p><span style="font-size: medium;">sa_handler字段包含一个信号捕捉函数的地址</span>
</p>
<p><span style="font-size: medium;">sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。</span>
</p>
<p><span style="font-size: medium;">sa_flag是一个选项,主要理解两个</span>
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;">SA_INTERRUPT 由此信号中断的系统调用不会自动重启<br>
SA_RESTART 由此信号中断的系统调用会自动重启</span>
</code>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;">SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针</span>
</code>
</span>
</p>
</td>
</tr></tbody></table>
<p><span style="font-size: medium;">最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他,具体有些烦,暂时用不到,不看了。</span>
</p>
<p><span style="font-size: medium;">下面的代码是用sigaction实现signal函数:</span>
</p>
<p><span style="font-size: medium;"></span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><code><span style="color: #000000;"><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">include</span>
<span style="color: #ff00ff;">"apue.h"</span>
<br>
Sigfunc <span style="color: #0000cc;">*</span>
<span style="color: #ff0000;">signal</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">int</span>
signo<span style="color: #0000cc;">,</span>
Sigfunc <span style="color: #0000cc;">*</span>
func<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br><span style="color: #0000ff;">struct</span>
<span style="color: #ff0000;">sigaction</span>
act<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//新的信号关联信息<br></span>
<br><span style="color: #0000ff;">struct</span>
<span style="color: #ff0000;">sigaction</span>
oact<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//老的信号关联信息<br></span>
<br>
act<span style="color: #0000cc;">.</span>
sa_handler <span style="color: #0000cc;">=</span>
func<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//新的信号处理函数<br></span>
<br><span style="color: #ff0000;">sigemptyset</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">&amp;</span>
act<span style="color: #0000cc;">.</span>
sa_mask<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//初始化屏蔽字<br></span>
<br>
act<span style="color: #0000cc;">.</span>
sa_flags <span style="color: #0000cc;">=</span>
0<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//初始化flags<br></span>
<br><span style="color: #0000ff;">if</span>
<span style="color: #0000cc;">(</span>
signo <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
SIGALRM<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">{//不会重启动</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">ifdef</span>
SA_INTERRUPT<br>
act<span style="color: #0000cc;">.</span>
sa_flags <span style="color: #0000cc;">|</span>
<span style="color: #0000cc;">=</span>
SA_INERRUPT<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">endif</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000ff;">else</span>
<span style="color: #0000cc;">{ //重启动</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">ifdef</span>
SA_RESTART<br>
act<span style="color: #0000cc;">.</span>
sa_flags <span style="color: #0000cc;">|</span>
<span style="color: #0000cc;">=</span>
SA_RESTART<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">endif</span>
<br><span style="color: #0000cc;">}</span>
<br><span style="color: #0000ff;">if</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff0000;">sigaction</span>
<span style="color: #0000cc;">(</span>
signo<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">&amp;</span>
act<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">&amp;</span>
oact<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&lt;</span>
0<span style="color: #0000cc;">)//新老交换</span>
<br><span style="color: #0000ff;">return</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff0000;">SIG_ERR</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">return</span>
<span style="color: #0000cc;">(</span>
oact<span style="color: #0000cc;">.</span>
sa_handler<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
</span>
</code>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><br></span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;"><br></span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="font-size: medium;">于signal 函数和 sigaction 函数的区别<br><br>
注意 : <br>
&lt;1&gt; sigaction <br>
*一般用法:<br>
  19<br>
20 phan.sa_handler = &amp;sig_handler;<br>
21 sigemptyset(&amp;phan.sa_mask);<br>
23 phan.sa_flags = 0; 或 //phan.sa_flags = SA_RESTART; 其效果和signal 一样<br>
24 sigaction(SIGALRM, &amp;phan, NULL);<br><br><br><br>
*注意<br><strong>一般不是重启动的函数,除非把sa_flag=SA_RESTART.</strong>
也就是说当信号到来,中断其阻塞的I/O操作,或其他阻塞的操作时,<br>
他们会自动启动这些操作,而不会中断这些操作.而这些I/O操作会保持原来的阻塞状态就好好象根本没有信号到来一样.<br><br>
&lt;2&gt;signal <br><strong> 函数是重启动的,</strong>
当使用该函数安装信号处理函数时,其阻塞的操作将会被中断<br><br>
实际使用例子:<br><br></span>
</p>
<pre class="Csharp"><span style="font-size: medium;">/*<br>
* test for alarm<br>
*/<br>
#include "apue.h"<br>
void sig_handler(int signo);<br>
void sig_handler2(int signo);<br>
void pr_mask(const char *str);<br>
int<br>
main(void)<br>
{<br>
int i;<br>
struct sigaction phan;<br>
char str[100] = {'/0'};<br>
//phan.sa_handler = &amp;sig_handler2;<br>
phan.sa_handler = &amp;sig_handler;<br>
sigemptyset(&amp;phan.sa_mask);<br>
//phan.sa_flags = SA_RESTART;  //如果使用这一行,将会阻塞在read函数<br>
phan.sa_flags = 0;<br>
sigaction(SIGALRM, &amp;phan, NULL);<br>
//signal(SIGALRM, sig_handler2);<br>
for(i=0;;i++){<br>
alarm(3);<br>
fprintf(stderr, "do something/n");<br>
read(STDIN_FILENO, str, sizeof(str));<br>
fprintf(stderr, "[%d] done/n", i);<br>
//alarm(0);<br>
//pause();<br>
}<br>
return(0);<br>
}<br>
void sig_handler(int signo)<br>
{<br>
struct sigaction phan;<br>
switch(signo){<br>
case SIGALRM: <br>
//如果下面的函数将会阻塞在read函数.因为它会让阻塞的操作自动重启动   <br>
//signal(SIGALRM, sig_handler);<br>
phan.sa_handler = &amp;sig_handler;<br>
sigemptyset(&amp;phan.sa_mask);<br>
phan.sa_flags = 0;<br>
sigaction(SIGALRM, &amp;phan, NULL);<br>
pr_mask("sig_handler : ");  //打印出信号掩码<br>
fprintf(stderr, "time out/n");<br>
break;<br>
default:<br>
fprintf(stderr, "[%d] ignores/n", signo);<br>
}<br>
}<br>
void sig_handler2(int signo)<br>
{<br>
switch(signo){<br>
case SIGALRM:<br>
fprintf(stderr, "time out/n");<br>
break;<br>
default:<br>
fprintf(stderr, "[%d] ignores/n", signo);<br>
}<br>
}<br>
void<br>
pr_mask(const char *str)<br>
{<br>
sigset_t    sigset;<br>
int         errno_save;<br>
errno_save = errno;     /* we can be called by signal handlers */<br>
if (sigprocmask(0, NULL, &amp;sigset) &lt; 0){<br>
fprintf(stderr, "sigprocmask error");<br>
exit(1);<br>
}<br>
printf("%s", str);<br>
if (sigismember(&amp;sigset, SIGINT))   printf("SIGINT ");<br>
if (sigismember(&amp;sigset, SIGQUIT))  printf("SIGQUIT ");<br>
if (sigismember(&amp;sigset, SIGUSR1))  printf("SIGUSR1 ");<br>
if (sigismember(&amp;sigset, SIGALRM))  printf("SIGALRM ");<br>
/* remaining signals can go here */<br>
printf("/n");<br>
errno = errno_save;<br></span>
</pre>
分享到:
评论

相关推荐

    信号捕捉函数sigaction

    sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)

    c处理函数 学习c精通必备

     定义函数 int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);  函数说明 sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和...

    sigaction.c 文件

    sigaction.c 文件下载后直接编译运行,详情看博客

    Linux系统调用 sigaction 的用法

    sigaction 函数原型定义如下:  int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact)  这个系统调用的作用是改变进程接收到的指定信号的行动。  使用这个函数需要包含头文件#...

    Linux进程通信之信号

    sigaction函数的具体介绍

    设置网络延时的时长(练习)

    利用setsockopt函数和sigaction函数分别实现修改网络延时的时长

    linux下几种最常用的IPC接口,这样一来,统一了接口,提高代码重用性.rar

    linux除了支持Unix早期信号语义函数signal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);...

    linux下system函数的简单分析

    简单分析了linux下system函数的相关内容,具体内容如下 int __libc_system &#40;const char *line&#41; { if (line == NULL) /* Check that we have a command processor available. It might not be available ...

    linux 下实现sleep详解及简单实例

    linux 下实现sleep详解及简单实例 sleep: 普通版本 1、基本设计思路:  1&gt;注册SIGALRM信号的处理函数;  2&gt;调用alarm(nsecs)设定闹钟;  3&gt;调⽤pause等待,内核切换到别的进程运行;  4&gt;nsecs秒之后,闹钟超时,内...

    UNIX环境高级编程_第二版中文

    10.14 sigaction函数  10.15 sigsetjmp和siglongjmp函数  10.16 sigsuspend函数  10.17 abort函数  10.18 system函数  10.19 sleep函数  10.20 作业控制信号  10.21 其他特征  10.22 小结  习题 ...

    UNIX环境高级编程 pdf格式

    10.14 sigaction函数 223 10.15 sigsetjmp 和siglongjmp函数 226 10.16 sigsuspend函数 229 10.17 abort函数 234 10.18 system函数 235 10.19 sleep函数 240 10.20 作业控制信号 241 10.21 其他特征 243 10.22 小结 ...

    UNIX环境高级编程部分

    10.14 sigaction函数 10.15 sigsetjmp 和siglongjmp函数 10.16 sigsuspend函数 10.17 abort函数 10.18 system 函数 10.19 sleep函数 10.20 作业控制信号 10.21 其他特征 10.21.1 信号名字 10.21.2 SVR4信号处理程序...

    UNIX环境高级编程

    10.14 sigaction函数 10.15 sigsetjmp 和siglongjmp函数 10.16 sigsuspend函数 10.17 abort函数 10.18 system 函数 10.19 sleep函数 10.20 作业控制信号 10.21 其他特征 10.21.1 信号名字 10.21.2 SVR4信号处理程序...

    Linux被中断的系统如何调用详解

    前言 慢系统调用,指的是可能永远无法返回,从而使进程永远... 如果信号处理函数是用sigaction注册的 默认情况下,系统调用不会自动重启,函数将返回失败,同时errno被置为EINTR 只有中断信号的SA_RESTART标志有效时

    UNIX环境高级编程(第二版中文)

    10.14 sigaction函数 261 10.15 sigsetjmp和siglongjmp函数 266 10.16 sigsuspend函数 268 10.17 abort函数 274 10.18 system函数 276 10.19 sleep函数 280 10.20 作业控制信号 282 10.21 其他特征 ...

    unix环境编程电子书

    248 10.8 可靠信号术语和语义 250 10.9 kill和raise函数 251 10.10 alarm和pause函数 252 10.11 信号集 256 10.12 sigprocmask函数 258 10.13 sigpending函数 259 10.14 sigaction函数 261 10.15 ...

    C例子:IPC-sigaction

    该程序是我写的博客“一起talk C栗子吧(v第八十六回:C语言实例--使用信号进行进程间通信三)”的配套程序,共享给大家使用

Global site tag (gtag.js) - Google Analytics