First step to Signal —— in Linux C Programing
1. What's signal
信号是软件中断,提供了一种处理异步事件的方法。(见《Unix环境高级编程》)一般使用时需包含 signal.h 库。
每个信号命名由SIG开头,实际值为正整数。(不存在编号为0的信号,0有特殊用途)
具体信号列表卡参见《Unix环境高级编程》 或者
2. signal 函数
信号机制最基础的接口是signal函数,声明如下:
// Original Definition
void ( *signal(int signum, void (*handler)(int)) ) (int); // Readable Definition
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
第二行是最原始的表示方法,利用typedef我们可提高可读性,得到第5和6行的声明。
一般带有指针的handler都代表一个处理函数的指针。
由line 6 我们可得知,signal函数表示将一个参数为信号的函数handler注册到一个信号上,即一旦触发该信号,该信号就会作为参数传给函数handler立即执行。或者说,信号一旦触发,该函数handler就会捕捉该信号,覆盖掉系统默认动作。(有一些如SIGSTOP等的信号不可被捕捉或忽略)
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> void handler(int sig) {
printf("\nSignal comes!\n");
} int main() {
printf("pid:%ld\n",(long)getpid());
signal(SIGINT, handler); getchar(); return ; }
执行上列程序,输入时按ctrl+c(SIGINT中断条件)试试?
3. kill 和 raise
定义如下
int kill(pid_t pid, int signo);
int raise(int signo); /* 两者关系 */
pid_t self = getpid(); raise(signo) == kill(self, signo);
kill函数是当前进程将信号发给对应的进程pid,而raise则是当前进程向自身发信号。(因此有上面的等式)
kill的pid参数有以下情况:
- pid > 0 将信号发送给pid进程
- pid == 0 将信号发送给与当前进程属于同一进程组的所有进程
- pid < 0 将信号发送给(-pid)进程组,前提是当前进程有权限向其发送信号
- pid == -1 将信号发送给所有当前进程有权限发送信号的进程
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> void handler(int sig) {
printf("\nSignal comes!\n");
} int main() {
printf("pid:%ld\n",(long)getpid());
signal(SIGINT, handler); // raise(SIGINT);
kill(getpid(), SIGINT); return ; }
注释可以互换一下,结果是一样的。
4. 信号集
信号集可以理解成多个信号的集合。
常用的函数如下:
int sigemptyset(sigset_t *set); // 置空集合
int sigfillset(sigset_t *set); // 使set包括所有信号
int sigaddset(sigset_t *set, int signo); // 将信号添加到集合
int sigdelset(sigset_t *set, int signo); // 将信号从集合中删除
// 以上函数成功返回 0, 错误返回 -1 int sigismamber(const sigset_t *set, int signo); // 判断信号是否在集合中
// 以上函true返回1, false返回0,出错返回-1
5. sigaction
sigaction 既是一个函数的名字也是一个结构体的名字,他们的定义分别如下:
int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
// 成功返回0,出错返回-1 struct sigaction {
void (*sa_handler)(int); // 信号处理函数
sigset_t sa_mask; // 作为该信号集合的标识
int sa_flags;
/* alter handler */
void (*sa_sigaction)(int, siginto_t *, void *);
}
【待定】
6. 信号阻塞
sigprocmask 函数
int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
// 成功返回0,出错返回-1
how 参数有三种选择:
- SIG_BLOCK 相当于set 与 oset的并集作为阻塞信号,set为新添加想要阻塞的信号。 相当于&mask = &oset , mask = set | oset
- SIG_UNBLOCK 相当于¬set 与 oset的交集作为阻塞信号,set为想要解除信号的集合。 相当于&mask = &oset , mask = ~set & oset
- SIG_SETMASK 新阻塞集合直接等于set的集合。相当于 &mask = &oset, mask = set
如果 set 为 NULL, 则不会改变当前进程的信号屏蔽字,how取值无意义。有时利用这点用来取得当前进程阻塞信号的集合变量。
#include <stdio.h>
#include <signal.h> void check() {
sigset_t set;
printf("====START\n");
if(sigprocmask(, NULL, &set)<)
{
printf("Sigprocmask error!!\n");
exit(-);
}
if(sigismember(&set,SIGINT))
printf("sigint\n"); printf("====END\n"); } void handler() {
printf("\nSignal comes!\n");
} int main() {
sigset_t blockset, oldblockset; signal(SIGINT, handler); sigemptyset(&blockset); check(); sigaddset(&blockset,SIGINT);
check(); sigprocmask(SIG_SETMASK,&blockset,&oldblockset);
check(); sigprocmask(SIG_SETMASK,&oldblockset,NULL); // clear mask set
check(); return ;
}
运行结果:

First step to Signal —— in Linux C Programing的更多相关文章
- Step one : 熟悉Unix/Linux Shell 常见命令行 (三)
3.学会使用一些管理命令 ps/top/lsof/netstat/kill/tcpdump/iptables/dd 端口查看 ps -- process status ps aux 观察程序所有程序 ...
- xenomai内核解析之信号signal(一)---Linux信号机制
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...
- Linux C Programing - Arguments(2)
#include <iostream> #include <stdlib.h> #include <stdio.h> //printf #include <u ...
- Linux C Programing - Terminal(1)
#include <stdio.h> //getchar() putchar() printf() gets() puts() sprintf() #include <stdlib. ...
- Step one : 熟悉Unix/Linux Shell 常见命令行 (四)
4.了解/etc目录下的各种配置文章,学会查看/var/log下的系统日志,以及/proc下的系统运行信息 了解/etc目录下的各种配置文章 /etc/hosts 主机配置文件 /etc/netwo ...
- Step one : 熟悉Unix/Linux Shell 常见命令行 (二)
2.学会使用一些文本操作命令 sed -- stream editor 1. Sed简介sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pat ...
- Step one : 熟悉Unix/Linux Shell 常见命令行 (一)
1.文件系统结构和基本操作 ls - - list directory contents -a/A 列出全部文件(包含隐藏文件) - i 列出inode号码 -n 查看UID and GID -d ...
- linux signal之初学篇
前言 本博文只总结signal的应用,对signal的kernel实现暂不讨论. 1. linux signal是什么? signal是linux提供的用于进程间通信的一种IPC机制. 2. 如何发送 ...
- Linux 学习 step by step (2)
Linux 学习 step by step (2) Linux,想要我说爱你真的不容易了,尽管,你是ubutun,尽管,你有蛮界面.但是,操作你,还是没有操作windows那么的如鱼得水了.为了更 ...
随机推荐
- 在 Github 上找「好东西」的方法
使用 Github 的站内搜索,搜索: Awesome + 你的关键字
- .net中c#获取本机IP地址实例代码
* 在使用前,一定要注意在头部加上引用: using System.Net; 代码如下: using System; using System.Collections.Generic; using S ...
- Android 实现分页(使用TabWidget/TabHost)
注:本文为转载,但该内容本人已亲身尝试,确认该方法可行,代码有点小的改动,转载用作保存与分享. 原作者地址:http://gundumw100.iteye.com/blog/853967 个人吐嘈:据 ...
- int类型的正负数转换
int aid = -this.id; 不能直接转 必须先赋值给一个变量 int c = this.id; int a = c * (-1); this.id = a;
- 签名、BOM头、编码、Windows记事本编码、java编码解码的那些事
对于Windows记事本: ANSI :GB2312 java中应使用GBK解码 Unicode :有签名的UTF-16LE java中应使用UTF-16解码 Unicode big endian : ...
- 去除ios系统a标签点击时的灰色背景
使用图片作为a标签的点击按钮时,当触发touchstart的时候,往往会有一个灰色的背景,想要去掉的话可以用下面这种方式 a,a:hover,a:active,a:visited,a:link,a:f ...
- ListView加checkBox可以实现全选等功能
1.效果图 2.LIteView_item布局 <?xml version="1.0" encoding="utf-8"?> <Relativ ...
- filedownload
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC "-/ ...
- Android编程容易犯的错误之二
11.不要太相信工具,比如Eclipse里面的断点遇到多线程什么,经常不起作用/走不到,还有就是如果语句为空的也不会走,这时候别太早下结论断点地方出错了, 所以每个工程都应该有日志的开关,通过查看日志 ...
- 搭建Git服务器
在远程仓库一节中,我们讲了远程仓库实际上和本地仓库没啥不同,纯粹为了7x24小时开机并交换大家的修改. GitHub就是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想 ...