Linux下信号的基本使用与分析
来源:互联网 发布:java自学什么书比较好 编辑:程序博客网 时间:2024/06/05 15:04
1.基本概念
信号是事件发生时对进程的通知机制,一个进程可以想另一个进程发送信号,此做法可以实现进程间的同步,然而给进程发信号的通常都是内核
(1)内核一般都会在发生以下事件时给进程发信号
.硬件发生异常
.用户键入了能够产生信号的终端特殊字符
.发生了软件事件
针对每一个信号,都定义了一个唯一的整数
(2)如果内核要调度该进程,等待信号就会马上送达,然而有时进程不想中断代码,进程可以将该信号添加到进程的信号掩码中,此信号将处于等待状态,知道进程将其从信号掩码中解除出来
(3)信号到达后,进程根据具体信号执行如下操作
.忽略信号:内核将信号丢弃,信号对进程不产生影响终止进程:进程异常终止
.停止进程:暂停进程的执行
具体的信号都是由信号处理函数来执行的
2.信号类型和默认行为
3.自定义信号处理函数signal()
#include<signal.h>sighandler_t signal(int sig,sighandler_t handler);
第一个参数sig,标注希望修改的信号编号,第二个参数handler,则指明信号到达时,所调用的处理函数,singal的返回值为之前改信号的处理函数
特别注意:我们可以用SIG_IGN来取代handler参数,它的作用是忽略该信号,如果信号专为此进程而生,则内核会丢弃此信号
4.信号处理器
信号处理器程序(信号捕捉器)是指当指定信号传递给进程时会调用一个函数
调用信号处理器程序会打断主程序流程,内核代表进程来处理程序,当处理完之后,主程序会从打断的位置恢复执行
具体实例
//为SIGINT信号重设的处理函数#include<stdio.h>#include<signal.h>void sigHanler(int sig){ printf("hello,world\n");}int main(){ int i; if(signal(SIGINT,sigHanler) == SIG_ERR) { printf("error\n"); } for(i=0;i<3;i++) { printf("haha\n"); sleep(2); }}
运行结果如下:
5.发送信号:kill()
#include<signal.h>int kill(pid_t,int sig);//成功返回0,失败-1
该调用将会杀掉指定pid的进程,sig则指定了要发送的信号
.如果pid大于0,那么信号发给pid指定的进程
.pid等于0发给同组的每个进程
.pid小于-1,发送给pid绝对值下属的所有进程
.pid等于-1,调用进程有权将信号发给每个进程
6.用kill()检查进程的存在
若将sig参数置为0,则无信号发送,相反kill()仅回去执行错误检查,查看是否可以向进程发送信号。这意味着,可以用其来检查一个进程是否存在,若调用成功那么进程存在。但是这并不能保证该pid的进程就一定存在,有可能该pid指的进程已不是先前的那个进程了
判断进程存在与否的其他方法:
(1)wait()系统调运:监控子进程是否存在
(2)信号量和文件锁:如果进程持有这些,那么如果不能取得这些,就以为这进程存在
(3)/proc/PID接口:如果进程存在,目录proc/12345将存在
7.显示信号描述
#include<signal.h>char *strsignal(int sig);//返回可打印字符串
8.信号集
当系统调用需要一组不同的信号时,就用到了信号集,信号集的数据结构为sigset_t
(1)信号集的初始化
#include<signal.h>int sigemptyset(sigset_t *set);
(2)向set中添加或删除单个信号
#include<signal.h>int sigaddset(sigset_t *set,int sig);int sigdelset(sigset_t *set,int sig);
(3)判断sig是否在set中
#include<signal.h>int sigismember(const sigset_t *set,int sig);
9.信号掩码
内核会为每个进程维护一个信号掩码,即一组信号,并将阻塞其对进程的传递。如果将遭阻塞的信号发送给进程,对该信号的传递将延后,直至从信号掩码中移除该信号
sigprocmask系统调用:
#include<signal.h>int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
sigprocmask()调运即可修改进程的信号掩码,又可获取现有掩码,或者俩重功效兼具,how参数指定给信号掩码带来的变化
10.等待状态的信号以及排队
若进程接收了一个正在阻塞的信号,则它会将该信号添加到进程的等待信号集中,不管该信号被发了多少此,在该信号被解除阻塞时,都只会给进程传递一次
11.改变信号处置:sigaction()
#include<signal.h>int sigaction(int sig,const struct sigaction *act,struct sigaction *oldact);
.sig参数标识想要获取或改变的信号编号
.act参数是指针,指向描述信号新处置的数据结构
.oldact参数用来返回之前信号处置的相关信息,若不想获取设为NULL
sigaction结构定义如下
struct sigaction{ void (*sa_handle)(int); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void);//不给应用程序使用}
其中sa_flags字段是一个位掩码,指定用于控制信号处理过程的各种选项(可以相或)
12.pause()
#include<unistd.h>int pause(void)
调用pause()函数将暂停进程的执行,直至信号处理函数中断该调用为止
- Linux下信号的基本使用与分析
- linux下kill信号的详细分析
- linux下 signal信号机制的透彻分析与各种实例讲解
- linux下 signal信号机制的透彻分析与各种实例讲解
- Linux 信号与信号处理分析
- linux下的信号
- Linux下的信号
- linux下的信号
- linux下中断与信号
- Linux信号的使用
- linux 信号的使用
- linux信号机制的分析
- linux下select,poll,epoll的使用与重点分析
- linux 下 signal 与sigaction 对信号的处理差异
- linux 下 alarm 与 SIGALRM 信号的一个小程序
- Linux下信号的产生与递达
- Linux下的信号(一)----信号的基本概念与产生
- linux下的信号处理
- 线程管理之线程创建和运行
- linux_c 网络开发日记(2)GDB简介
- moodle的一些api翻译~$page翻译
- java 常用 Java 静态代码分析工具的分析与比较
- !HDU 4193 循环序列前缀和非负-单调队列-(区间最值)
- Linux下信号的基本使用与分析
- 通过Cloudera Manager为datanode增加数据目录
- C# 对于时间的相关问题
- zend studio 10破解/汉化
- 有关artTemplate模板的问题。
- 学习笔记:linuxc第六章下
- malloc free函数
- Maven安装和配置
- moodleAPI翻译~$output