信号屏蔽

信号忽略:系统仍然传递该信号,只是相应的进程不做任何处理

信号屏蔽:进程不捕获信号,信号处于未决状态,当不再屏蔽信号时可以捕获之前被屏蔽的信号。

信号集数据结构定义:

typedef __sigset_t sigset_t;
#define _SIGSET_NWORDS (1024 / (8 * sizeof(unsigned long int)))
typedef struct
{
//此结构体占据32 * 32 = 1024 bit 每bit对应一个信号 val[0]0-31位对应常用1-31信号
unsigned long int __val[_SIGSET_NWORDS];
}__sigset_t;

int sigprocmask (int __how, __const sigset_t *__restrict __set, sigset_t * __restrict __oset) :设置屏蔽信号集。成功0,否则-1.

第一个参数:更改该集的方式

  • SIG_BLOCK : 将第2个参数描述的集合添加到当前进程屏蔽的信号集中
  • SIG_UNBLOCK : 将第2个参数描述的集合从到当前进程屏蔽的信号集中删除
  • SIG_SETMASK : 无论之前屏蔽了哪些信号,设置当前屏蔽集为第2个参数描述的对象。

如果set是空指针,则how没有意义,不会更改屏蔽信号集,因此可以查询当前屏蔽的信号集合。

int sigpending (sigset_t * __set) :获取当前未决的信号。成功0,否则-1.

int sigemptyset (sigset_t * __set) :  清空信号集

int sigfillset (sigset_t * __set) :将set的所有位都置为1.

int sigaddset (sigset_t *__set, int __signo) : 添加信号到信号集set

int sigdelset (sigset_t * __set, int __signo) : 从set中删除信号

int sigismember (__const sigset_t *__set, int __signo) : 检测信号是否在信号集,是返回1,否则返回0

int sigisemptyset (__const sigset_t * __set) : 检测信号集是否为空信号集

int sigandset (sigset_t *__set, __const sigset_t *__left, __const sigset_t *__right) : 用逻辑与的方式将两个信号合并

int sigorset (sigset_t *__set, __const sigset_t *__left, __const sigset_t *__right) : 用逻辑或的方式将两个信号合并

当一个信号在处理的过程中,相同的信号会暂时屏蔽,防止信号处理嵌套。

等待信号

int pause (void) :等待除了当前屏蔽信号集合外的任意信号

int sigsuspend (__const sigset_t * __set) :将当前进程屏蔽的信号集替换为其参数所指定的信号集合,直到收到非指定集合中的信号才继续执行

注意 不能屏蔽SIGKILL和SIGSTOP

信号应用例子

功能是复制文件,父进程执行复制操作,如果收到SIGUSR1信号则打印当前复制进度;子进程每隔固定时间向父进程发送SIGUSR1信号,通过SIGALARM

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<stdlib.h>
int count; //当前复制大小
int file_size; //文件大小
void sig_alarm(int arg); //处理alarm信号
void sig_usr(int sig); //处理普通信号SIGUSR1
int main(int argc, char *argv[])
{
pid_t pid;
int i;
int fd_src, fd_des;
char buf[]; //复制操作临时空间
if(argc != )
{
printf("check the format:comm src_file des_file\n");
return -;
}
if((fd_src = open(argv[], O_RDONLY)) == -)
{
perror("open file src");
exit(EXIT_FAILURE);
}
file_size = lseek(fd_src, , SEEK_END); //获取资源文件大小
lseek(fd_src, , SEEK_SET); //重新设置读写位置为文件头
if((fd_des = open(argv[], O_RDWR|O_CREAT, )) == -)
{
perror("open fd_fdes");
exit(EXIT_FAILURE);
}
if((pid = fork()) == -)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(pid > )
{
signal(SIGUSR1, sig_usr); //安装信号SIGUSR1
do
{
memset(buf, '\0', );
if((i = read(fd_src, buf, )) == -)
{
perror("read");
exit(EXIT_FAILURE);
}
else if(i == ) //如果复制完毕,向子进程发送SIGINT信号,终止子进程
{
kill(pid, SIGINT);
break;
}
else
{
if(write(fd_des, buf, i) == -)
{
perror("write");
exit(EXIT_FAILURE);
}
count += i; //更新已经复制的大小
}
}while(i != );
wait(pid, NULL, ); //等待子进程退出
exit(EXIT_SUCCESS);
}
else if(pid == )
{
usleep();
signal(SIGALRM, sig_alarm); //安装SIGALRM信号
ualarm(, );
while();
exit(EXIT_SUCCESS);
}
} void sig_alarm(int arg)
{
kill(getppid(), SIGUSR1); //向父进程发送SIGUSR1信号
}
void sig_usr(int sig)
{
float i;
i = (float)count/(float)file_size;
printf("current over : %0.0f%%\n", i *);
}

功能可以实现,但是奇怪的是ualarm中的数字,即使我改成很大,比如ualarm(100,1000) 信息输出的还是很密集,感觉跟 ualarm(1,1)的没有区别??按理说时间间隔应该变长啊?

【linux高级程序设计】(第十章)Linux异步信号处理机制 3的更多相关文章

  1. 【linux高级程序设计】(第十二章)Linux多线程编程 4

    读写锁 书上有读者写者的代码,我实在是懒得实现一遍了.跟之前的代码差不多. 多线程异步信号处理 int pthread_kill (pthread_t __threadid, int __signo) ...

  2. Linux程序设计学习笔记——异步信号处理机制

    转载请注明出处: http://blog.csdn.net/suool/article/details/38453333 Linux常见信号与处理 基本概念 Linux的信号是一种进程间异步的通信机制 ...

  3. 【linux高级程序设计】(第十六章)网络服务器应用设计

    xinetd服务介绍 xinetd是Linux下的一个网络守候进程,用来统一管理网络负载不大的一组小型网路服务. 一些小型的网络服务,比如时间,telnet服务,不以守候进程出现,而是让xinetd服 ...

  4. 【linux高级程序设计】(第十五章)UDP网络编程应用 4

    socket信号驱动 为了使一个套接字能够使用信号驱动I/O,至少需要以下3步操作. 1.安装SIGIO信号 2.套接字的拥有者设定为当前进程.因为SIGIO信号只会送到socket拥有者进程. 通过 ...

  5. 【linux高级程序设计】(第十二章)Linux多线程编程

    线程与进程对比 1.用户空间对比 2.内核空间资源对比 在创建线程时,Linux内核仍然创建一个新的PCB来标识这个线程.内核并不认为进程与线程有差别. 进程是操作系统管理资源的基本单元,线程时Lin ...

  6. 【linux高级程序设计】(第十一章)System V进程间通信 2

    消息队列 消息队列是消息的链式队列,模型如下: 包括两种数据结构: msqid_ds消息队列数据结构 msg消息队列数据结构 struct msg_msg{ struct list_head m_li ...

  7. 【linux高级程序设计】(第十一章)System V进程间通信 1

    System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...

  8. 【linux高级程序设计】(第九章)进程间通信-管道 1

    Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...

  9. 【视频】 Linux高级程序设计01.2开发平台及Linux环境限制

    [课程笔记] Linux环境限制 遵循规范,使用现有资源,明确系统限制,增量开发. (1)规范问题 编码的规范,让程序更易读.Linux编码规范. “见着如意”:变量,函数命名等能够让人看到名称就知道 ...

随机推荐

  1. 绿盟python测试实习面试

    1.简历问题 低级错误:时间写错 最近好像越来越马大哈了,总是犯低级错误. 上次的开题报告首页,这次的时间,每次都有小问题,确是大毛病 到底哪里出错了 2 RHCE证书好像没有用 面试官根本就不懂这个 ...

  2. easyui 获取树的平级根节点的父节点&选择性展示树的一个根节点

    1.easyui的树的根节点一般是几个平级的,怎样获取这些父节点的id? 可以将获取到的平级根节点放在一个数组中 var roots=[]; roots=$("#tree1").t ...

  3. 线性表(List)

    1.什么是线性表(List)? 零个或多个数据元素的有限序列. (1)元素之间是有序的. (2)线性表强调是有限的. 2.线性表有哪些操作? (1)线性表的创建和初始化,InitList (2)判空, ...

  4. HTTP协议中POST方法和GET方法有那些区别?

    GET用于向服务器请求数据,POST用于提交数据 GET请求,请求参数拼接形式暴露在地址栏,而POST请求参数则放在请求体里面,因此GET请求不适合用于验证密码等操作 GET请求的URL有长度限制1k ...

  5. Python+Selenium框架设计篇之-什么是POM

    前面我们介绍了Python中的单元测试框架unittest,以后我们所有的测试类文件,都采用unittest来辅助我们进行debug和脚本开发.搞定了debug机制和确定了unittest来进行创建和 ...

  6. Restful API实战

    简介:随着移动互联网的发展,客户端层出不穷,app,web,微信端等等,而后端业务逻辑基于是一致的,如何做到业务逻辑“一次编写,随时接入”?答案是通过远程调用API,而目前比较火的方案是“Restfu ...

  7. iframe 如何让它展现内容自适应高度

    引用: <iframe id="ifm1" runat="server" src="/comment/page1?id=@productId&q ...

  8. RelativeLayout布局属性

    Android RelativeLayout属性 // 相对于给定ID控件 android:layout_above 将该控件的底部置于给定ID的控件之上; android:layout_below ...

  9. jquery实现京东淘宝首页的轮番效果图

    主要是绑定事件以及实现自动滚轮 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  10. 使用awk根据多维度统计系统tps

    业务简单日志格式: [2017-08-28 01:00:00.523]transfer_search,7001045,1708271100083774377,20170827,,,,,,,,,,001 ...