Linux信号函数
1. signal函数:
#include <signal.h> void (*signal(int signo, void (*func)(int)))(int); ret-成功返回信号以前的处理配置 出错返回SIG_ERR
比较容易理解的形式:
typedef void Sigfunc(int); Sigfunc *signal(int, Sigfunc *);
三个宏定义:
#define SIG_ERR (void(*)())-1 //这里应该是早期写法 函数声明 不检查参数类型 #define SIG_ERR(void(*) (int))-1
#define SIG_DFL (void(*)())0
#define SIG_IGN (void(*)())1
SIG_ERR: 信号注册失败返回SIG_ERR
SIG_DFL: 采用系统对此信号的默认动作;
SIG_IGN: 忽略此信号,注意SIGKILL和SIGSTOP不能忽略;
这三个宏定义不是一定要使用上面的三个值,但是必须是不能声明函数的地址;
2. 进程启动和创建都信号影响;
程序启动:当执行一个程序时,所有信号的状态都是系统默认或者忽略。通常所有的信号都被设置成他们的默认动作,除非调用exec的进程忽略该信号。确切的讲,exec函数将原先设置为要捕捉的信号都更改为它们的默认动作,其他信号的状态则不变;(对于一个进程原先要捕捉的信号,当其执行了一个新程序后,自然不能再捕捉它了,因为信号捕捉函数的地址很可能在所执行的新程序文件中已无意义)
进程创建:当一个进程调用fork时,其子进程继承父进程的信号处理方式。因为子进程在开始时恢复了父进程的存储映像,所以信号捕捉函数的地址在子进程中是有意义的;
3. kill和raise函数:
kill函数将信号发送给进程组。raise函数则允许进程向自身发送信号;
#include <signal.h> int kill(pid_t, int signo);
int raise(int signo);
raise(signo) == kill(getpid(), signo)
kill函数pid参数:
pid>0: 发送信号给进程ID为pid的进程;
pid==0: 发送信号给与发送进程属于同一进程组的所有进程,而且发送进程具有向这些进程发送信号的权限;
pid<0: 发送信号给其他进程组ID等于pid的绝对值,而且发送进程具有向这些进程发送信号的权限;
pid==-1: 发送信号给发送进程有权限向他们发送信号的系统上的所有进程;
4. alarm和pause函数
#include <unistd.h> unsigned int alarm (unsigned int seconds); ret - 0或者以前设置的闹钟时间的余留秒数
alarm函数设定一个定时器,经过指定的seconds秒后会产生一个SIGALRM信号;如果不忽略或者不捕捉,其默认动作是终止进程;
如果第一次设置的没有超时,那么第二次设置的时候alarm返回第一次设置的余留秒数作为返回值,并且旧闹钟被替代;如果本次参数为0,则取消第一次的闹钟,返回余留秒数;
#include <unistd.h> int pause(void); ret- -, 并将erron设置为EINTR
pause只有执行了一个信号处理程序并从其返回时,pause才返回,在这种情况下,pause返回-1,并设置errno为EINTR;
5. 信号集:
#include <signal.h> int sigemptyset(sigset_t *set); //初始化由set指向的信号集,清除其中所有信号
int sigfillset(sigset_t *set); //初始化由set指向的信号集,包含其所有信号
int sigaddset(sigset_t *set, int signo); //添加信号到信号集
int sigdelset(sigset_t *set, int signo); //删除信号到信号集 ret-成功返回0 失败返回- int sigismember(const sigset_t *set, int signo); //某信号是否为信号集成员
ret-真返回1,假返回0,出错返回-
6. sigprocmask函数
#include <signal.h> int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
首先,若oset!=NULL,那么进程当前的信号屏蔽字通过oset返回;
其次,若set!=NULL,则参数how指示了如何修改当前信号屏蔽字;
注意,不能阻塞SIGKILL和SIGSTOP
how-SIG_BLOCK: 该进程信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集;set包含了我们希望阻塞的附加信号;
SIG_UNBLOCK: 该进程信号屏蔽字是其当前信号屏蔽字和set指向信号集补集的交集;set包含我们希望解除阻塞的信号;
SIG_SETMASK: 该进程的信号屏蔽字将被set指向的信号集来替代;
如果SET==NULL,则how无意义;
7. sigpending函数:
#include <signal.h> int sigpending(sigset_t *set); ret-成功返回0 出错返回-1
函数返回信号集,其中各个信号对于调用进程是阻塞的而不能递送的,因而也一定是当前未决的;
8. sigaction函数:
#include <signal.h> int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact); ret-成功返回0 出错返回-
9. sigsuspend函数:
#include <signal.h> int sigsuspend(const sigset_t *sigmask); ret- -,并errno设置为EINTR
函数提供了一个原子操作中先恢复信号屏蔽字,然后使进程休眠;
将进程的信号屏蔽字的值设置为由sigmask指向的值。在捕捉到一个信号或者发生了一个会终止该进程的信号之前,该进程将被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,并且将该进程的信号屏蔽字设置为调用sigsuspend之前的值;
10. abort()函数:
#include <stdlib.h> void abort(void);
此函数将SIGABRT信号发送给调用进程。让进程捕捉该信号的意图是,在进程终止前由其执行所需清理操作。
12. sleep()函数:
#include <unistd.h> unsigned int sleep(unsigned int seconds); ret-0或者未休眠的秒数
此函数使调用进程被挂起,直到满足以下条件之一:
(1) 已经过了seconds所指定的墙上时钟时间;
(2) 调用进程捕捉到一个信号并从信号处理程序中返回;
n. 测试代码:
#include <unistd.h>
#include <stdio.h>
#include <signal.h> static void sig_user(int signo)
{
if (signo == SIGUSR1){
printf("reveived SIGUSR1\n");
}
else if (signo == SIGUSR2){
printf("reveived SIGUSR2\n");
}
} int main()
{
if (signal(SIGUSR1, sig_user) == SIG_ERR){
perror("can't catch SIGUSR1\n");
} if (signal(SIGUSR2, sig_user) == SIG_ERR){
perror("can't catch SIGUSR2\n");
} for ( ; ; ){
pause();
} return ;
}
Linux信号函数的更多相关文章
- Linux信号、信号处理和信号处理函数
信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式.在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可 ...
- Linux信号
信号本质上就是一个软件中断,它既可以作为两个进程间的通信的方式, 更重要的是, 信号可以终止一个正常程序的执行, 通常被用于处理意外情况 ,* 信号是异步的, 也就是进程并不知道信号何时会到达 $ki ...
- Linux信号基础
Linux信号基础 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux进程基础一文中已经提到,Linux以进程为单位来 ...
- Linux信号(signal) 机制分析
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- [置顶] Linux信号相关笔记
最近又温习了一遍Linux中的信号知识,发现有很多东西以前没有注意到,就通过这篇博客记录一下,巩固一下知识点. 一,信号基础: 信号是什么?为了回答这个问题,首先要从异常说起,这里的异常不是指c++/ ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- Linux信号实践(2) --信号分类
信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...
- 非常好的一篇对linux信号(signal)的解析 (转载)【转】
转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...
- linux select函数详解
linux select函数详解 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核: •我们所关心的文件描述符 •对每个描述符,我们所关心的状 ...
随机推荐
- cookie的路径决定服务器在发送请求时候 是否决定发送 当路径匹配时候 则发送给服务器(默认发送原则)
1.cookie路径默认为当前访问地址的上一级路径 2.当前访问地址的路径包含了cookie的路径 则发送给访问的地址 3.路径决定cookie发送与否 4.发送包含在当前路径里面的cookie
- bzoj3998-弦论
给定一个长度为\(n(n\le 5\times 10^5)\)的字符串,求它的第\(k\)小字串.有两种模式: \(Type=0\),不同位置的相同字串只算一个 \(Type=1\),不同位置相同字串 ...
- 2011 Multi-University Training Contest 4 - Host by SDU
A.Color the Simple Cycle(polya计数+字符串匹配) 此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP. 于是把原串和原串扩大两倍 ...
- Linq的模糊查询(包含精确模糊查询)
目录: 1.判断是否为空或者null 2.普通包含模糊查询 1)以某字符串开头的模糊查询 2)以某字符串结尾的模糊查询 3)包含某字符串的模糊查询 3.精确到字符串对应位数字符的模糊查询(*重点) l ...
- 一些技巧 && 常数优化 && 出现の错误
开坑原因 7.21 今天DTZ大爷教了我一个算欧拉函数的好方法......是质因数复杂度的 这让我想到,这些小技巧小idea,很多时候,可能就是考场上最致命.最一击必杀的"大招" ...
- [ZJOI2010]贪吃的老鼠 网络流
---题面--- 题解: 这是一道强题emmmm,做法非常巧妙,,,我也是看了好久大佬题解才看明白一点 首先考虑没有限制的情况,即n个老鼠可以在同一时刻吃同一块奶酪 对各个时间段拆点,连奶酪 ---& ...
- 洛谷4578 & LOJ2520:[FJOI2018]所罗门王的宝藏——题解
https://www.luogu.org/problemnew/show/P4578 https://loj.ac/problem/2520 有点水的. 先转换成图论模型,即每个绿宝石,横坐标向纵坐 ...
- BZOJ1027 [HNOI2004]打鼹鼠 【dp】
1207: [HNOI2004]打鼹鼠 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3647 Solved: 1746 [Submit][Sta ...
- layui中对表格操作按钮集的判断
可用如下语法: {{# if(d.IsAudit==false){ }} <a class='layui-btn layui-btn-xs layui-btn-normal' lay-event ...
- Codeforces Round #401 (Div. 2) A B C 水 贪心 dp
A. Shell Game time limit per test 0.5 seconds memory limit per test 256 megabytes input standard inp ...