信号屏蔽

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

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

信号集数据结构定义:

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. luoguP1726 上白泽慧音

    P1726 上白泽慧音 题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村 ...

  2. SparkSteaming中直连与receiver两种方式的区别

    SparkStreaming的Receiver方式和直连方式有什么区别? Receiver接收固定时间间隔的数据(放在内存中的),使用高级API,自动维护偏移量,达到固定的时间才去进行处理,效率低并且 ...

  3. VSX-5 VSXMusic 编码听音乐

    给VS写个扩展来听音乐的说法,缘来已久,这两天做了个初版,使用豆瓣FM,先发出来. 插件现在只做了VS2013的,别的版本有待下一步支持. 现在暂时只有一个Adornment(就是那个有封面的),一个 ...

  4. 《Cracking the Coding Interview》——第18章:难题——题目2

    2014-04-29 00:59 题目:设计一个洗牌算法,效率尽量快点,必须等概率. 解法:每次随机抽一张牌出来,最后都抽完了,也就洗好了.时间复杂度O(n^2),请看代码. 代码: // 18.2 ...

  5. 《Cracking the Coding Interview》——第8章:面向对象设计——题目9

    2014-04-23 23:57 题目:如何设计一个内存文件系统,如果可以的话,附上一些代码示例. 解法:很遗憾,对我来说不可以.完全没有相关经验,所以实在无从入手.这题目应该和工作经验相关吧? 代码 ...

  6. Centos在VMware虚拟机上的网络配置一记

    症状:配置好了IP, ping  127.0.0.1   ok ping  10.0.0.1   ok ping  外网IP,域名     network is unreachable ------- ...

  7. python负数除法与模运算

    1.负数除法: >>> print 45/76>>> print -45/7-7 >>> print 45/-7-7 >>> p ...

  8. Python全栈工程师(Linux基本操作)

    ParisGabriel         Python 入门基础        Linux :Ubuntu操作系统   首先我们说的是Linux操作系统常用的快捷键以及终端命令   一. VMware ...

  9. Linux常用命令及工具记录(持续更新)

    一.命令 convmv   作用:文件名的编码转换   安装:sudo apt-get install convmv   使用:convmv * -f gbk -t utf8 --notest   c ...

  10. 2 26requests.py

    """ requests """ # import requests # reponse = requests.get("http ...