《UNIX级别编程环境》注意读出信号(2)
1.功能sigaction
sigaction动与指定信号相关联的处理动作。其函数原型例如以下:
#inlcude <signal.h>
int sigaction(int signo,const struct sigaction * restrict act,struct sigaction * restrict act);
当中參数signo是要检測或改动其详细动作的信号编号。
若act指针非空,则要改动其动作。假设oact指针非空。则系统经由oact指针返回该信号的上一个动作。结构体sigaction的结构例如以下:
一旦对给定的信号设置了一个动作,那么在调用signation显式的改变它之前,该设置就一直有效。
act结构的sa_flags字段指定对信号进行处理的各个选项。下图具体列出了这些选项的意义。
sigaction结构的sa_sigaction字段是一个替代的信号处理程序。
当sa_flags设置了SA_SIGINFO标志时,使用该信号处理程序。
通常,信号处理函数的形式是这种:void handler(int signo)。
但假设设置了SA_SIGINFO标志,则信号处理函数的原型是这种:void handler(int signo,siginfo_t *info,void
*context)。siginfo_t结构包括了信号产生原因的有关信息。
该结构的样式例如以下所看到的:
context參数是无类型指针。它可被强制类型转换为ucontext_t结构类型,该结构标识信号传递时的上下文信息。
2.函数sigsetjmp和siglongjmp
在信号处理程序中进行非局部转移时使用这两个函数。
#include <setjmp.h>
int sigsetjmp(sigjmp_buf env,int savemask);//若直接调用,返回0。若从siglongjmp调用返回,则返回非0。
void siglongjmp(sigjmp_buf env,int val);
在调用sigsetmask时。假设savemask值为1,则将进程当前的屏蔽字保存在env中。
调用siglongjmp时,假设带非0savemask的sigsetjmp调用已经将进程的屏蔽字保存在env中了。则siglongjmp从中恢复保存的信号屏蔽字。
例:
#include "apue.h"
#include <setjmp.h>
#include <time.h> static void sig_usr1(int);
static void sig_alrm(int);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump; void pr_mask(const char *str)//打印当前被堵塞的信号
{
sigset_t sigset;
int errno_save; errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0)
perror("sigprocmask error"); printf("mask: %s", str);
if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM "); /* remaining signals can go here */ printf("\n");
errno = errno_save;
} Sigfunc * signal(int signo,Sigfunc * func)
{
struct sigaction act,oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
} else {
act.sa_flags |= SA_RESTART;
}
if(sigaction(signo,&act,&oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
} int main(void)
{
if(signal(SIGUSR1,sig_usr1) == SIG_ERR)
err_sys("signal(SIGUSR1) error"); if(signal(SIGALRM,sig_alrm) == SIG_ERR)
err_sys("signal(SIGALRM) error"); pr_mask("starting main:"); if(sigsetjmp(jmpbuf,1)) {
pr_mask("ending main:");
exit(0);
}
canjump = 1;
for(;;)
pause();
} static void sig_usr1(int signo)
{
time_t starttime; if(canjump == 0)
return; pr_mask("starting sig_usr1:"); alarm(3);
starttime = time(NULL);
for(;;)
if(time(NULL) > starttime+5)
break;
pr_mask("finishing sig_usr1:");
canjump = 0;
siglongjmp(jmpbuf,1);
} static void sig_alrm(int signo)
{
pr_mask("in sig_alrm:");
}
3.函数sigsuspend
#include <signal.h>
int sigsuspend(const sigset_t * sigmask);
进程的信号屏蔽字设置由sigmask指定。
在捕捉到一个信号前,该进程被挂起。假设捕捉到一个信号,则sigsuspend返回,而且该进程的新高屏蔽字设置为曾经的值。
例:
#include "apue.h" static void sig_int(int); void pr_mask(const char *str)//打印当前被堵塞的信号
{
sigset_t sigset;
int errno_save; errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0)
perror("sigprocmask error"); printf("mask: %s", str);
if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM "); /* remaining signals can go here */ printf("\n");
errno = errno_save;
} Sigfunc * signal(int signo,Sigfunc * func)
{
struct sigaction act,oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
} else {
act.sa_flags |= SA_RESTART;
}
if(sigaction(signo,&act,&oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
} int main(void)
{
sigset_t newmask,oldmask,waitmask; pr_mask("program start:"); if(signal(SIGINT,sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
sigemptyset(&waitmask);
sigaddset(&waitmask,SIGUSR1);
sigemptyset(&newmask);
sigaddset(&newmask,SIGINT); if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0)
err_sys("SIG_BLOCK error"); pr_mask("in critical region:"); if(sigsuspend(&waitmask) != -1)
err_sys("suspend error"); pr_mask("after return from sigsuspend:"); if(sigprocmask(SIG_SETMASK,&oldmask,NULL) < 0)
err_sys("SIG_SETMASK error"); pr_mask("program end:");
} static void sig_int(int signo)
{
pr_mask("in sig_int:");
}
4.函数sigqueue
使用排队信号必须做一下几个操作:
(1)使用sigaction函数安装信号处理程序时指定SA_SIGINFO标志。
(2)在sigaction结构的sa_sigaction成员中提供信号处理程序。
(3)使用sigqueue函数发送信号。
#include <signal.h>
int sigqueue(pid_t pid,int signo,const union sigval value);
5.信号名和编号
能够通过psignal函数可移植地打印与信号编号相应的字符串。
#include <signal.h>
void psignal(int signal,const char * msg);//字符串msg输入到标准错误流
假设只需要字符信号的叙述性说明,可以用于strsignal功能。
#include <string.h>
char *strsignal(int signo);
《UNIX级别编程环境》注意读出信号(2)的更多相关文章
- 记录一次配置unix网络编程环境的过程和遇到的问题
记录一次搭建unix网络编程环境过程中遇到的问题和总结 计算机环境虚拟机 linuxmint-18-xfce-64bit 1.打开unix网络编程.iso 把目录下的文件复制到某一目录,修改权限,可命 ...
- unix网络编程环境搭建
unix网络编程环境搭建 网络编程 环境 1.点击下载源代码 可以通过下列官网中的源代码目录下载最新代码: http://www.unpbook.com/src.html 2.解压文件 tar -xz ...
- UNIX网络编程 环境搭建
配置好动态链接库或者静态链接库 1,下载UNIX网络编程书的头文件及示例源码unpv13e 2 按照readme来编译 Execute the following from the src/ d ...
- Unix系统编程()改变信号处置:signal
Unix系统提供了两种方法来改变信号处置:signal和sigaction.这篇描述的是signal系统调用,是设置信号处理的原始API,所提供的接口比sigaction简单.另一方面,sigacti ...
- Unix系统编程()发送信号的其他方式:raise和killpg
有时,进程需要向自身发送信号,raise 函数就执行了这一任务. #include <signal.h> int raise(int sig); 在单线程程序中,调用raise相当于对ki ...
- Unix系统编程()发送信号kill
与shell的kill命令类似,一个进程能够使用kill系统调用向另一进程发送信号. 之所以选择kill作为术语,因为早期UNIX实现中大多数信号的默认行为是终止进程. #include <si ...
- ubuntu14.04下unix网络编程环境的配置
建议 unpv13e/README看一下,忽略一下内容 ===================================================================== 操作 ...
- unix网络编程环境配置程序运行
1 查看ubuntu版本 cat /etc/issue 2 查看版本 cat /proc/version 3 下载 你可以通过其他方式下载 这里下载好了 文件名为unpv13e 4 开始配置 (1)c ...
- ubuntu14.04下unix网络编程 环境的配置
在ubuntu下 首先:在unpv13e文件加下 ./configure cd lib make cd ../libfree make cd ../liggai make cd .. vim lib/ ...
随机推荐
- Ubuntu下用NdisWrapper安装网卡驱动
下面是一个简单全面的使用NdisWrapper的指南.这是从Beginning Ubuntu Linux, Second Edition中提炼出来的. 这份指南是第8章的一部分.该章给出了在Ubunt ...
- C#读书
C#读书雷达 大家都知道,ThoughtWorks的技术雷达每年都会发布两到三次,它不但是业界技术趋势的标杆,更提供了一种卓有成效的方法论,即打造自己的技术雷达.在这种思想的驱动下,我们诞生了自己 ...
- Java Web整合开发(附录1) - 安装配置环境
1. Install JDK http://blog.csdn.net/sonnet123/article/details/9169741 Download JDK http://www.oracle ...
- Oracle使用并行建索引须要注意的问题
建索引时.我们为了建索引快.会加上并行,加上并行之后.此列索引就会是并行了. 訪问有并行度的索引时,CBO可能可能会考虑并行运行.这可能会引发一些问题,如在server资源紧张的时候用并行会引起更加严 ...
- android学习经常使用的数据文件夹
android工程实践 1.仿360一键清理实现(一) "一键清理"是一个桌面图标,点击图标后,显示一个视图.进行清理动画.之后显示清理了几个进程,释放了多少M内存.点击" ...
- CentOS7下一个mysql安装
CentOS7安装MySQL --下载mysql http://mirrors.sohu.com/mysql/MySQL-5.6/ http://mirrors.sohu.com/mysql/MySQ ...
- solr与.net课程(七)solr主从复制
既然solr是解决大量数据全文索引的方案,因为高并发的问题,我们就要考虑solr的负载均衡了,solr提供很easy的主从复制的配置方法,那么以下我们就来配置一下solr的主从复制 如果我们在192. ...
- cocos2dx-2.x CCFileUtils文件管理分析(2)
于1于,我只是对整体结构进行了分析,然后,2于,我会在一些我们经常使用的分析功能. //获取给定文件名称的全路径 //以下这非常长一段凝视.通过举样例,像我们说明cocos2dx获取文件全路径的规则. ...
- 4.锁定--Java的LockSupport.park()实现分析
LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了主要的线程同步原语. LockSupport实际上是调用了Unsafe类里的函数.归结到Unsafe里,仅仅有两个函数: ...
- C/S通信模型和相关技术要点
差点儿全部的项目中,都会涉及到client和服务端.而client与server之间的通信又是一个非经常见但又有须要问题的技术问题. 首先,连接方式有长连接和短连接.先看看概念. 长连接短连接仅仅是一 ...