Linux 对信号的总结
Linux信号_总结
对信号本质的理解:
类似于中断,区别在于中断是由硬件产生的,而信号是由软件实现的。
信号的来源:
触发硬件(触发键盘,或是硬件故障);软件信号函数kill 、alarm、setitimer、sigqueue 等函数。
信号的分类:
可靠信号与不可靠信号,实时信号与非实时信号;
不可靠信号:
SIGRTMIN前的信号称为不可靠信号,在早期这段信号可能做出错误的反应,或是丢失。因此对此段信号成为不可靠信号。
可靠信号:
在SIGRTMIN与SIGRTMAX之间的信号称做可靠信号,可靠信号是为了防止信号丢失的。这些信号可以排队处理。
实时信号与非实时信号:
非实时信号都不支持排队,都是不可靠信号;实时信号都是支持排队的,都是可靠信号;
对信号的响应:
响应的三种方式
(1)忽略信号
有两个特殊的信号SIGKILL 和SIGSTOP信号不能被忽略。
(2)捕捉信号
给对应的信号绑定响应的处理函数,带到信号产生时,执行对应的函数。
(3)执行缺省信号
进程对实时信号的缺省反应时进程的终止。
信号的发送:
发送信号的函数有,kill(), alarm(),raise(),setitimer();
(1)kill(int pid, int signal);
PID参数 | 信号的就收进程 |
---|---|
pid>0 | 进程的ID为pid的进程 |
pid=0 | 同一个进程组 |
pid<0 && pid!=-1 | 进程组ID为pid绝对值的所有进程 |
pid=-1 | 发送至所有ID大于1的进程 |
参数介绍:
pid为进程号,singnal为信号值。
kill常用于pid>0的信号处理,调用成功返回0,否则返回-1。
(2)alarm(unsigned int seconds)
专门为SIGALRM信号而设函数,seconds表示时间,此函数意味着在seconds秒后向SIGALRM信号发送消息。
进程调用alarm后,以前的alarm()调用都将无效。若调用alarm()前,进程中已经设置了闹钟,则返回上一个闹钟生于的时间,否则返回0;
eg:
#include<signal.h>
#include<stdio.h>
int main(void)
{
printf("first time return:%d\n",alarm(4));
sleep(1);
printf("after sleep(1),remain:%d\n",alarm(2));
printf("renew alarm,remain:%d\n",alarm(1));
}
//运行结果为
first time return:0
after sleep(1),remain:3
renew alarm,remain:2
(3)raise(int signal);
此函数时向本进程发送signal信号的,signal为即将发送的信号值。调用成功返回0;否则返回 -1。
(4)setitimer()函数
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
结构体介绍:
struct itimerval
{
struct timeval it_interval;//间隔时间
struct timeval it_value; //初始时间
};
struct timeval
{
long tv_sec; //秒
long tv_usec; //微妙
};
参数描述:
which:表示定时器类型,setitimer有三种定时器类型。
ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL : 设定程序执行时间;经过指定的时间后,内核将发送SIGVTALRM信号给本进程;
ITIMER_PROF : 设定进程执行以及内核因本进程而消耗的时间和,经过指定的时间后,内核将发送ITIMER_VIRTUAL信号给本进程;
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;
eg:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
void sigroutine(int signo) {
switch (signo) {
case SIGALRM:
printf("Catch a signal -- SIGALRM\n");
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM\n");
break;
}
}
int main(int argc, char ** argv) {
struct itimerval value,ovalue,value2;
printf("process id is %d\n",getpid());
signal(SIGALRM, sigroutine); //为SIGALRM信号绑定sigroutine函数
signal(SIGVTALRM, sigroutine); //为SIGVTALRM信号绑定sigroutine函数
value.it_value.tv_sec = 1;//设定起始时间
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;//设定终止时间
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue);
value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
for (;;) ;
}
//运行结果为
process id is 3136
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
安装信号:
由signal()、sigaction()处理:
(1)signal(int signum, sighandler_t handler);
此函数的作用是,为handler函数,或处理过程绑定一个信号,每当出现信号后,进行handler处理。
signum:所指信号;
handler:处理过程,可以时函数的指针。这个也可设置为"SIG_IGN",表示忽略此信号,"SIG_DFL"表示以系统默认方式处理此信号。(注意:SIGKILL SIGSTOP不可被安装)
此函数的例子可参考上一个例子。
(2)sigaction();
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
signum:指定的信号(除SIGKILL,SIGSTOP外)
sigaction:指向结构指针,指定对特定信号的处理
oldact:指向的对象用来保存原来对相应信号的处理
sigaction()函数中第二个参数最为关键。
sigaction结构体如下:
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags; //会影响信号接受特殊标志
void (*sa_restorer)(void);
};
(1)结构体中的sa_restorer已经不使用可以忽略。
(2)sa_handler指定的处理函数只有一个参数类似于使用signal()函数
(3)sa_sigaction也是指定信号的处理函数,不过可以带三个参数:
第一个参数为信号值;
第二个参数是指向siginfo_t结构的指针;
第三个参数没有使用;
siginfo_t结构体如下:
siginfo_t
{
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused
hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count; POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since Linux 2.6.32) */
};
(4)sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。
注:请注意sa_mask指定的信号阻塞的前提条件,是在由sigaction()安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。
(5)sa_flags标志位:
当sa_flags设置为SA_SIGINFO时,示信号附带的参数可以传递到信号处理函数中。即使sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。
信号,介绍先到此,如若觉得又不对的地方,请指出,共同进步谢谢!
参考博客有:
https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
http://www.cnblogs.com/dandingyy/articles/2653218.html
Linux 对信号的总结的更多相关文章
- linux kill信号列表
linux kill信号列表 $ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL5) SIGTRAP 6) ...
- Linux进程间通信——信号集函数
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- linux 自定义信号
从来没试过linux自定义信号,查了下,说是系统只提供了SIGUSR1和SIGUSR2两个,就两个够吗?更要命的是如果要自定义信号如#define SIG_MYSIG ....的话要改内核才行,哥 ...
- Linux 的信号和线程
什么是线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成,每一个程序都至少 ...
- Linux之信号
产生信号五种方法: 按键产生:ctrl+c.ctrl+z.ctrl+\ 系统调用产生:如kill.raise.baort 软件条件产生:如定时器alarm 硬件异常产生:非法访问内存(段错误).除0( ...
- Linux&C ——信号以及信号处理
linux信号的简单介绍 信号的捕捉和处理 信号处理函数的返回 信号的发送 信号的屏蔽 一:linux信号的简单介绍. 信号提供给我们一种异步处理事件的方法,由于进程之间彼此的地址空间是独立的,所以进 ...
- Linux&C ——信号以及信号处理
linux信号的简单介绍 信号的捕捉和处理 信号处理函数的返回 信号的发送 信号的屏蔽 一:linux信号的简单介绍. 信号提供给我们一种异步处理事件的方法,由于进程之间彼此的地址空间是独立的,所以进 ...
- linux有关信号的FAQ
1.为什么会出现系统调用被中断的情况? 进程在执行一个低速系统调用而阻塞期间捕捉到一个信号时,该系统调用就被中断不再继续执行.该系统调用返回出错,其errno被设置为EINTR.这样处理的理由是:因为 ...
- Linux 发送信号
使用kill命令 --在命令行执行kill命令.向指定进程发送信号. 使用kill函数 int kill(pid_t pid,int sig); --参数pid指定一个要杀死的进程,而sig是要发送的 ...
- Linux进程间通信-信号
1.什么是信号信号是Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会执行相应的操作. 2.信号的产生1)由硬件产生,如从键盘输入Ctrl+C可以终止当前进程2)由其他进程发送,如可在s ...
随机推荐
- spring从服务器磁盘读取图片,然后显示于前端页面上
需求是,前台通过传参,确定唯一图片,然后后台在服务器磁盘中读取该图片,然后显示于前台页面上. 后台代码: @RequestMapping("unit/bill/showeinvoice&qu ...
- python(list、字典、元组、字符串方法、文件读写)草稿
1.list 定义list a = [] 添加元素 a.append('xx') #在list末尾添加 a.insert(0,'abc') #在指定某位置添加元素.指定的下标不存在就在末尾添加 ...
- RN-入门基础
Props State 一切界面变化,都是state变化 state修改必须通过setState方法 this.state.like=true 这样复制无效 setState是一个merge合并的操作 ...
- Flutter windows环境安装 + 模拟设备 + 项目运行
目录: 一.JDK安装 1.1.JDK下载 1.2.环境变量配置 1.3.测试 二.ANDROID-SDK安装 2.1.下载 2.2.环境变量配置 三.Flutter安装 3.1.下载 3.2.环境变 ...
- css修改整个项目的滚动条样式
在项目中,滚动条不可避免的药出现.设置统一规范的滚动条也是必然.用一个独立的css文件即可修改整个项目中的滚动条样式 . scrollBar.css: /* 滚动条有滑块的轨道部分 */ ::-web ...
- DeprecationWarning
当我在导入sklearn这个库的时候,程序抛出了一个丢弃警告,它的意思是在版本更新后imp库已经不用了,用importlib来代替这个库 Warning (from warnings module): ...
- expected_conditions模块提供了判断页面元素的16种方法
1.title_is: 判断当前页面的title是否完全等于(==)预期字符串,返回布尔值2.title_contains : 判断当前页面的title是否包含预期字符串,返回布尔值3.presenc ...
- (Python基础)简单购物车代码
以下是最简单,最基础的购物车代码,一起学习,一起参考.product_list = [ ('Iphone',5800), ('Mac Pro',15800), ('car',580000), ('co ...
- Spark启动报错|java.io.FileNotFoundException: File does not exist: hdfs://hadoop101:9000/directory
at org.apache.spark.deploy.history.FsHistoryProvider.<init>(FsHistoryProvider.scala:) at org.a ...
- Https证书配置
本文介绍配置免费证书的方法 具体步骤: 一.获取免费CA证书 步骤1到腾讯云找到: 二.申请完成 后域名验证指引 申请域名型证书,可以通过以下方式验证域名的所有权: 1. 手动 DNS 验证 通过解析 ...