struct sigaction{
void (*sa_handler)(int);
//在调用前加入信号屏蔽字,仅当信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值*/
sigset_t sa_mask;
//Signal options
int flags;
//结构中还有一个参数,不懂。
}
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void show_handler(int sig)
{
printf("I got signal %d\n", sig);
int i;
for(i = 0; i < 5; i++) {
printf("i = %d\n", i);
sleep(1); //for inputting interupt signal
}
}
int main(void)
{
int i = 0;
struct sigaction act, oldact;
act.sa_handler = show_handler;
sigaddset(&act.sa_mask, SIGQUIT); //(1)加入信号集,屏蔽"CTRL+\"
act.sa_flags = SA_RESETHAND | SA_NODEFER; //(2)if signal got,set to SIG_DFL
//act.sa_flags = 0; //(3)
//sigprocmask(SIG_BLOCK,&act.sa_mask,NULL);/*This can be used for add sigset mask*/
sigaction(SIGINT, &act, &oldact);
while(1) {
sleep(1);
printf("sleeping %d\n", i);
i++;
}
}
结果如下:
(1)第一种情况,执行"CTRL+C", 在中断处理函数后再执行"CTRL+C"
$./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2
i = 3
i = 4
sleeping 1
sleeping 2
sleeping 3
sleeping 4 /*CTRL+C结束*/
说明:第二次"CTRL+C",由于act.sa_flags = SA_RESETHAND | SA_NODEFER 。SA_RESETHAND: 信号发给进程后,把信号处理器复位为缺省值SIG_DFL,所以第二次按"Ctrl+C"时, 信号处理器已经复位为SIG_DFL,对SIGINT来说,缺省动作就是终止进程。
(2)注:如果在信号SIGINT(Ctrl + C)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+\),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT,见如下结果
$./a.out
sleeping 0
sleeping 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2 /*CTRL+\*/
i = 3
i = 4
Quit
(3)第三种情况:"CTRL+C", "CTRL+C", "CTRL+\"
改act.sa_flags = SA_RESETHAND | SA_NODEFER;->act.sa_flags =SA_NODEFER;
[root@FPC10 zhisxu]# ./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1 /*somewhere here*/
i = 2 /*CTRL+\*/
i = 3
i = 4
i = 2
i = 3
i = 4
Quit
sigaction.sa_flags 控制内核对该信号的处理标记
SA_NODEFER 一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 -- SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)
SA_RESETHAND 当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)
SA_SIGINFO 信号处理函数是带有三个参数的sa_sigaction
*** 如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!
注: 阻塞的意思是延迟相应信号
原文地址:http://hi.baidu.com/xu_zhisheng/blog/item/82cbdfd7ab12872607088bdc.html
分享到:
相关推荐
### 信号捕捉函数sigaction详解 #### 一、引言 在计算机编程中,尤其是在Linux环境下,信号(Signal)作为一种重要的通信机制被广泛应用于进程间通信。为了更好地控制信号的行为,POSIX标准引入了`sigaction`函数...
sigaction.c 文件下载后直接编译运行,详情看博客
sigaction 函数原型定义如下: int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact) 这个系统调用的作用是改变进程接收到的指定信号的行动。 使用这个函数需要包含头文件#...
读者将学习如何使用signal()、raise()、sigaction()以及setitimer()等函数来处理信号和设定定时事件,这些技能对于编写响应系统事件和实现自动任务调度的程序非常有用。 总的来说,《Linux编程典型实例解析》的代码...
6. **信号处理**:`signal()`和`sigaction()`用于处理和安装信号处理器,这对于响应系统事件和异常情况非常关键。 7. **内存管理**:动态内存分配(`malloc()`, `calloc()`, `realloc()`, `free()`)和内存映射(`...
### 深入浅出:信号应用实例 #### 关键知识点概述 本文将根据所提供的文件信息,详细解析信号处理在Linux环境下的应用实例。主要内容包括信号处理的基本概念、信号处理函数的实现方法以及通过示例代码展示信号在...
该程序是我写的博客“一起talk C栗子吧(v第八十六回:C语言实例--使用信号进行进程间通信三)”的配套程序,共享给大家使用
本篇文章将详细解析在Linux环境下,C语言中的常用库函数,并通过实例进行讲解,帮助开发者更好地理解和应用这些函数。 1. **字符测试篇**: 在C语言中,`<ctype.h>`库提供了对字符的测试函数,如`isalpha()`用于...
实例4引入了`sigaction()`函数,它提供了比`signal()`更强大的功能,可以设置信号掩码(`sa_mask`)和标志(`sa_flags`)。在这里,`sa_handler`被设置为`my_func`,确保信号被正确处理。`sigemptyset()`清空了信号...
6. **信号处理**:`signal()`和`sigaction()`函数用于处理系统发送的信号,如SIGINT(Ctrl+C)和SIGTERM(终止信号)。 7. **系统调用**:Linux提供了丰富的系统调用接口,如`getpid()`获取进程ID,`sleep()`暂停...
`sigaction`函数用于设置信号处理函数和信号行为,`sigqueue`则用于携带自定义数据发送信号。程序会持续等待信号并每两秒发送一次,附加的数据是字符串"other info"。 在实际应用中,信号通信可以结合其他IPC机制,...
本文将深入探讨Linux IPC的六种主要方法,并通过具体的实例来讲解如何使用这些方法。首先,我们来看看标题中提及的"Linux-IPC-进程间通信实例"。 1. **管道(Pipes)**: 管道是一种半双工的通信方式,允许数据在...
本篇文章将深入探讨Linux信号机制,包括其基本概念、主要函数如`signal`和`sigaction`的使用方法,以及相关实例。 首先,信号是内核向进程传递信息的一种机制,它可以用来中断进程的正常执行,或者通知进程发生了...
linux 下实现sleep详解及简单实例 sleep: 普通版本 1、基本设计思路: 1>注册SIGALRM信号的处理函数; 2>调用alarm(nsecs)设定闹钟; 3>调⽤pause等待,内核切换到别的进程运行; 4>nsecs秒之后,闹钟超时,内...
8. **`sigaction()`函数**:比`signal()`更高级的信号处理函数,它可以提供更多的控制,如指定信号传递方式、处理行为等。 9. **线程与信号**:在多线程环境中,信号处理需要注意线程安全问题。默认情况下,信号会...
2. **初始化信号处理**:`init_sigaction()`函数设置信号SIGALRM的处理函数为`prompt_info()`。 3. **初始化定时器**:`init_time()`函数设置ITIMER_REAL定时器的初始值和周期值均为2秒。 4. **主函数**:`main()`...
总的来说,这个实例展示了如何在Linux环境中使用C语言编写一个简单的信号处理程序,通过设置信号处理函数和结构体`struct sigaction`来控制信号的处理方式。这对于理解和实践Linux下的进程间通信和错误处理至关重要...
定义函数 int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact); 函数说明 sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和...
这些实例将帮助你理解理论知识在实际编程中的应用。 总之,理解和熟练掌握Linux下的信号处理对于任何系统级编程者来说都是必备技能。通过学习和实践,你可以编写出更加健壮、响应迅速的Linux应用程序。记得结合提供...