linux c信号相关函数学习记录 - 范文中心

linux c信号相关函数学习记录

02/15

一、什么是信号    1、 信号就是软件中断,很多的程序都需要处理信号。信号提供了一种处理异步事件的机制。

例如:当用户在终端下运行一个程序时,用户在键盘键入一个中断键(CTRL+C),则会通过信号机制终止一个正在运行的程序。

2、每一个信号都有自己独特的名字。这些名字都是以SIG开头的。例如中断信号SIGINT.在linux下输入shell命令kill -l可以看到linux所支持的所有的信号名称以及信号的编号。其中1号到32号(32号信号用户是不能使用的)信号都是继承UNUX系统的信号。其余的是linux系统根据POSIX标注定义的信号。

3、在编写信号程序时,必须加上头文件。事实上,信号的定义的定义在另外的一个头文件中,但是该头文件又包含在中。

大家可以查看头文件/usr/include/signal.h 发现里边有一句include ,然后再查看头文件/usr/include/bits/signum.h  大家会发现信号的定义都在这里边.

二、信号产生的方式

1、用户按键,如用户按下了CTRL+C组合键

2、硬件异常,如除数为0,无效内存引用

3、进程调用kill函数将信号发送给一个进程或者进程组,限制条件是:接受信号进程和发送信号进程的所有者必须相同。或者发送信号的进程的所有者是超级用户

4、调用命令kill,实际上此命令是kill函数的接口

5、检测到某种软件条件已经发生。例如 SIGPIPE(管道的读进程已经终止后,另一个进程写此管道时产生)

当产生信号时,内核通常会在进程表中设置一个某种形式的标志,这就是所谓的向进程发送了一个信号。

三、进程的处理

1、捕捉信号,可以指定信号的处理函数,当捕捉的信号时自动执行此函数

2、忽略信号,除了SIGKILL和SIGSTOP,因为它们向超级用户提供了使进程终止或停止的方法。另外忽略了由某些硬件异常产生的信号(如无效内存引用),则进程运行的行为是不可预测的。

3、按照系统默认的方式处理,大部分信号的默认处理方式是终止进程,

四、信号的捕捉和处理

1、signal函数 -- 信号机制最简单的接口,用来设置进程在接受到信号时候的动作

在shell下输入man signal查看函数原型

#include

typedef void (*sighandler_t)(int);    //定义函数指针类型

sighandler_t signal(int signum, sighandler_t handler);

signum为信号的编号

handler为信号处理函数

执行成功是返回信号处理函数指针,不成功时返回-1

举例如下:

#include

#include

#include

/*信号处理函数*/

void handler_signal(int signo)

{

printf("receive a signal\n");

exit(0);

}

int main()

{

signal(SIGINT,handler_signal); //进程接收到中断信号(SIGINT),执行handler_signal函数

while(1);

return 0;

}

编译、运行程序

当用户按下CTRL+C组合键时,程序退出,输出receive a signal

这就是一个简单的关于信号的函数

2、sigaction函数

#include

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

sigaction函数用来检查或者设置进程在接收到信号时的动作。 signum为信号编号

act不为空指针,则为新的信号处理函数;

oldact不为空指针,则为旧的信号处理函数将储存在oldact中。

struct sigaction {

void (*sa_handler)(int);

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

void (*sa_restorer)(void);

};

sa_handler为信号处理函数的函数名 sa_sigaction也是信号处理函数的的函数名

sa_mask声明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加入到进程的信号屏蔽字中。仅当从信号捕捉函数返回时再进行进程的信号屏蔽字复位。这样在调用信号处理程序时候就能阻塞某些信号。

sa_flags设置对信号处理的一些选项。

具体的sigaction结构体的介绍,在使用man手册中会又详细的介绍。

举个简单例子:

#include

#include

#include

#include

void signal_handler1(int sig)

{

printf("I am signal_handler1\n");

printf("receive a signal!\n");

exit(0);

}

void signal_handler2(int sig)

{

printf("I am signal_handler2\n");

printf("receive a signal!\n");

exit(0);

}

int main()

{

struct sigaction sac1,sac2;

sac1.sa_handler = signal_handler1;

sac2.sa_handler = signal_handler2;

sigaction(SIGINT,&sac1,NULL);//设置信号的处理函数,将信号SIGNAL和信号处理函数signal_handler联系起来

//sigaction(SIGINT,&sac2,NULL);//重新设置信号的处理函数,将信号SIGNAL和信号处理函数signal_handler2联系起来

while(1);

exit(0);

}

编译、运行,结果显示执行了signal_handler1函数。 将sigaction(SIGINT,&sac2,NULL);注释去掉,重新编译运行,结果显示的是执行了signal_handler2

函数,

通过此例,说明sigaction函数可以设置信号处理函数,或者重新设置信号处理函数。

五、kill和raise函数

#include

#include

int kill(pid_t pid, int sig);

int raise(int sig);

kill函数将信号发送给进程或者进程组,但是前提是:接受信号进程和发送信号进程的所有者必须相同,即发送者和接受者的有效ID必须相同。或者发送信号的进程的所有者是超级用户 raise将信号发送个自己

raise(int sif)等价于kill(getpid(),int sig)

kill的pid参数

pid > 0   将信号发送给pid进程

pid == 0  将信号发送给和发送信号进程属于同一进程组的所有进程(这些进程的组ID等于发送进程的必须相同)

pid

pid == -1 将信号发送给发送进程有权限向它们发送信号的系统上的所有进程。

注意:上述的所有进程组都不包含某些特殊的系统进程。

六、alarm和pause函数

#include

unsigned int alarm(unsigned int seconds);

int pause(void);

alarm函数可以设置一个计时器。当计时器超时时,产生一个SIGALRM信号。如果不捕捉或者忽略这个信号,则其默认的动作就是终止调用alarm函数的进程

每个进程只能设置一个闹钟时钟,如果在调用alarm时,以前己为该进程设置了闹钟时钟,并且没有超时,则返回返回以前的闹钟的余留值作为本次alarm函数调用的返回值。以前的闹钟时钟被新值替换。若以前没有设置闹钟时钟,则调用alarm时,返回0

pause函数使进程挂起,直到捕捉到了一个信号。只有在执行了一个信号处理函数,并且从其返回时,pause才返回,在这种情况下,pause返回-1,并且将errno设置为EINTR。


相关内容

  • 进程间通信方式比较
    进程间的通信方式: 1.管道(pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 2.信号(signal): 信号是在软件层次上对中断机制 ...
  • 计算机三级嵌入式习题整理
    集成电路的工作速度主要取决于组成逻辑门电路的晶体管的尺寸.晶体管的尺寸越小,其极限工作频率越高,门电路的开关速度就越快. 在linux OS中,用"任务"替代"进程",而没有"进程" ...
  • 嵌入式系统在智能家居中的应用
    新疆工程学院 毕 业 论 文 题 目: 嵌入式系统在智能家居 中的应用 院(系): 计算机工程系 专业年级 : 通信技术10-02 姓 名 : 魏文华 学 号 : 2010230083 指导教师 : 贾勇 2013年04月17 论文题目:嵌 ...
  • 基于RaspberryPi实现的智能家居
    摘 要 本文以树莓派为载体进行智能家居控制器的设计.在对现在三种市面上的网络电视的比较中引出毕设的主角--树莓派.首先是LINUX 系统常识性的介绍:然后是在ARM/LINUX平台上面开发应用的两种方法:调用系统已有资源.做程序(C 经典法 ...
  • WinCE的实时性
    提到WinCE及工业控制,也许有人对WinCE的实时性能否满足工业控制要求产生疑问.诚然,WinCE的实时性不如QNX,也不如VxWOrks,但是大量文献表明WinCE的确是嵌入式实时操作系统,也在工业控制市场占有相当的份额.究其原因,离不 ...
  • Linux内核动态跟踪-SYstemTap
    导读 :Sloaris中的Dtrace技术曾获<华尔街杂志>2 006技术创新大奖中的金奖.在2005年底,Sun在清华大学举办了Sloaris技术讲座,其中的Dtrace技术,让人耳目一新,它让技术人员摆脱了苦苦阅读静态源代码 ...
  • 常见的嵌入式操作系统
    常见的嵌入式操作系统 分类: 嵌入式 操作系统2012-12-11 10:06 459人阅读 评论(1) 收藏 举报 嵌入式操作系统 嵌入式操作系统与通用的操作相比较主要特点在于: 1.小内核,稳定可靠. 2.需要可装卸.可裁剪,以便能灵活 ...
  • Linux命令nohup和screen命令的区别
    如果想在关闭ssh连接后刚才启动的程序继续运行怎么办,可以使用nohup.但是如果要求第二天来的时候,一开ssh,还能查看到昨天运行的程序的状态,然后继续工作,这时nohup是不行了,需要使用screen来达到这个目的. nohup命令可以 ...
  • 二阶运算放大器设计与仿真
    苏 州 市 职 业 大 学 实习(实训) 说明书 名称 2014年9月1日至2014年9月5日共1 周 院 部 电子信息工程学院 班 级 12微电子技术2班 姓 名 院 长 张 欣 系 主 任 指导教师 校外指导教师 目录 第一章 绪论 . ...
  • 电子实验室常用仪器使用
    实训项目一 示波器使用 示波器是一种常用的电子仪器,主要用于观察和测量各种电信号.是展示和观测电信号的电子仪器,可以直接测量信号电压的大小和周期.配合各种传感器把非电量转换成电量,示波器也可以用来观察各种非电量的变化过程.特别适用于观测瞬时 ...