【linux高级程序设计】(第十章)Linux异步信号处理机制 3
信号屏蔽
信号忽略:系统仍然传递该信号,只是相应的进程不做任何处理
信号屏蔽:进程不捕获信号,信号处于未决状态,当不再屏蔽信号时可以捕获之前被屏蔽的信号。
信号集数据结构定义:
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的更多相关文章
- 【linux高级程序设计】(第十二章)Linux多线程编程 4
读写锁 书上有读者写者的代码,我实在是懒得实现一遍了.跟之前的代码差不多. 多线程异步信号处理 int pthread_kill (pthread_t __threadid, int __signo) ...
- Linux程序设计学习笔记——异步信号处理机制
转载请注明出处: http://blog.csdn.net/suool/article/details/38453333 Linux常见信号与处理 基本概念 Linux的信号是一种进程间异步的通信机制 ...
- 【linux高级程序设计】(第十六章)网络服务器应用设计
xinetd服务介绍 xinetd是Linux下的一个网络守候进程,用来统一管理网络负载不大的一组小型网路服务. 一些小型的网络服务,比如时间,telnet服务,不以守候进程出现,而是让xinetd服 ...
- 【linux高级程序设计】(第十五章)UDP网络编程应用 4
socket信号驱动 为了使一个套接字能够使用信号驱动I/O,至少需要以下3步操作. 1.安装SIGIO信号 2.套接字的拥有者设定为当前进程.因为SIGIO信号只会送到socket拥有者进程. 通过 ...
- 【linux高级程序设计】(第十二章)Linux多线程编程
线程与进程对比 1.用户空间对比 2.内核空间资源对比 在创建线程时,Linux内核仍然创建一个新的PCB来标识这个线程.内核并不认为进程与线程有差别. 进程是操作系统管理资源的基本单元,线程时Lin ...
- 【linux高级程序设计】(第十一章)System V进程间通信 2
消息队列 消息队列是消息的链式队列,模型如下: 包括两种数据结构: msqid_ds消息队列数据结构 msg消息队列数据结构 struct msg_msg{ struct list_head m_li ...
- 【linux高级程序设计】(第十一章)System V进程间通信 1
System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...
- 【linux高级程序设计】(第九章)进程间通信-管道 1
Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...
- 【视频】 Linux高级程序设计01.2开发平台及Linux环境限制
[课程笔记] Linux环境限制 遵循规范,使用现有资源,明确系统限制,增量开发. (1)规范问题 编码的规范,让程序更易读.Linux编码规范. “见着如意”:变量,函数命名等能够让人看到名称就知道 ...
随机推荐
- laravel5.5容器
目录 1. 比较典型的例子就是 cache 缓存 2. 容器顾名思义,其实就是完成存取过程 2.1 绑定过程 简单绑定 绑定单例 绑定实例 绑定初始数据 2.2 解析过程 容器主要是为了实现控制反转, ...
- LDAP操作的两种方案
最近由于项目需要研究了一下LDAP相关知识,感觉对没接触过的人来说还是有点坑的,所以记录下来给大家分享. 由于是第一次接触,就在网上搜了一些相关的文章,照着示例代码测试,却怎么也连不上LDAP服务器, ...
- DOS程序员手册(七)
第11章 中断处理程序 本章将深入到DOS系统内部探讨中断处理程序的内容.与其他计算机编程不一样, 中断处理程序这个名词听起来就很难懂.用最简单的话来说,中断处理程序就是对应于中 断激活的程 ...
- python学习笔记十一:操作mysql
一.安装MySQL-python # yum install -y MySQL-python 二.打开数据库连接 #!/usr/bin/python import MySQLdb conn = MyS ...
- webdriver--设置元素等待
sleep():脚本执行到某一位置时“睡一会”,再继续执行:参数的单位是s:sleep方法由python的time模块提供,有两种引入和使用方式 import time time.sleep(5) f ...
- linux查看80端口占用情况
netstat -anltp|grep 80
- 小红帽安装centos的yum的一些坑!
[root@localhost ~]# lsanaconda-ks.cfg yum-3.4.3-158.el7.centos.noarch.rpm yum-updateonboot-1.1.31-45 ...
- 【志银】Win764位配置Github环境及将代码部署到Github pages-志银强势总结
(软件及教程下载分享:链接:http://pan.baidu.com/s/1dFysay9 密码:pug0) 1-安装Git-2.9.2-64-bit.exe(解压安装文件,运行安装程序,除了记得修改 ...
- Android记事本开发03
昨天: 生成签名文件及导出apk 遇到的问题: 无. 今天: activity和intent基础
- Codeforces Round #387 (Div. 2) 747F(数位DP)
题目大意 给出整数k和t,需要产生一个满足以下要求的第k个十六进制数 即十六进制数每一位上的数出现的次数不超过t 首先我们先这样考虑,如果给你了0~f每个数字可以使用的次数num[i],如何求长度为L ...