信号屏蔽

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

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

信号集数据结构定义:

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. 3437: 小P的牧场

    3437: 小P的牧场 思路 斜率优化. dp[i]表示到第i个点(第i个点按控制台)的最小代价. 代码 #include<cstdio> #include<iostream> ...

  2. 在ddms 里面查看data/data里面的东西 不显示data/data

    今天我要查看data/anr/tarces.txt,没办法,我只有root手机. 可是root之后,我发现还是不能查看或者导出traces.txt. 后来我才知道,root之后,文件夹权限没有变,所以 ...

  3. 怎么设置才能让外网ip可以访问mysql数据库[转]

    转自: http://www.hongyanliren.com/89.html 使用mysql中,很多人都会遇到这样的问题:在vps服务器或者云服务器上安装了mysql后,使用其他工具在外网ip之下根 ...

  4. 什么时候会报unrecognized selector的异常?

    当调用该对象上某个方法,而该对象上没有实现这个方法的时候, 可以通过“消息转发”进行解决,如果还是不行就会报unrecognized selector异常 objc是动态语言,每个方法在运行时会被动态 ...

  5. atomic integer 实现

    public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, ...

  6. apt-get阿里源

    备份原有配置文件 mv /etc/apt/sources.list /etc/apt/sources.list.bak 新建一个文件 vi /etc/apt/sources.list 复制以下内容到新 ...

  7. 孤荷凌寒自学python第四十一天python的线程同步之Event对象

     孤荷凌寒自学python第四十一天python的线程同步之Event对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 鉴于Lock锁与RLock锁均宣告没有完全完成同步文件操作的问题,于 ...

  8. hnust 分蛋糕

    问题 B: 分蛋糕 时间限制: 1 Sec  内存限制: 128 MB提交: 2430  解决: 966[提交][状态][讨论版] 题目描述 今天是DK生日,由于DK的朋友很多,所以DK在蛋糕店定制了 ...

  9. A - 最长上升子序列

    A - 最长上升子序列 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem De ...

  10. easyUI tree jQuery

    Tree 数据转换 所有节点都包含以下属性: id:节点id,这个很重要到加载远程服务器数据 which is important to load remote data text: 显示的节点文本 ...