《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/ ...
随机推荐
- 第1周 SQL Server 如何执行一个查询
原文:第1周 SQL Server 如何执行一个查询 大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Se ...
- 学习FFmpeg API – 解码视频
本文转载 视频播放过程 首先简单介绍以下视频文件的相关知识.我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的 ...
- 使用ZeroMQ(clrzmq)实现异步通信
ZeroMQ是对Socket的封装,通过组合多种类型的结点可以实现复杂的网络通信模式.而且ZeroMQ设计简单,可以有多种平台实现,对于跨平台项目是一个福音. clrzmq是ZeroMQ的C#语言的实 ...
- 【设计模式】Template Method模式
OO基金会 封装 多态 继承 OO原则 封装变化 多用组合,少用继承 针对接口编程.不针对实现编程 为交互对象的松耦合设计而努力 类应该对扩展开放,对改动关闭 依赖抽象,不要依赖详细类 仅仅和朋友交谈 ...
- python K-means工具包初解
近期数据挖掘实验,写个K-means算法,写完也不是非常难,写的过程中想到python肯定有包,尽管师兄说不让用,只是自己也写完了,而用包的话,还不是非常熟,略微查找了下资料,学了下.另外,自己本身写 ...
- 使用order by和rownum时特别注意
起因 在项目中有用到某表作为数据来源,在页面以列表的形式显示.使用的数据库是Oracle,分页的时候使用到了rownum这个关键字.列表有排序功能,自然也用到了order by.接下来问题出现了,我在 ...
- JAVA字符串比较equals()和equalsIgnoreCase()差异
.用equals( )方法比較两个字符串是否相等.它具有例如以下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串(String)对象做比較的字符串( ...
- DataGridView显示数据的两种方法
1.简介 DataGridView空间是我们经常使用的显示数据的控件,它有极高的可配置性和可扩展性. 2.显示数据 DataGridView显示数据一般我们经常使用的有两种方法,一种是直接设置Data ...
- POJ 3177 Redundant Paths - from lanshui_Yang
Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...
- C#启动进程之Process
在程序设计中,我们经常会遇到要从当前的程序跳到另一个程序的设计需求.也就是当前进程创建另一个进程.C#提供了Process使得我们很方便的实现. 1.Process基本属性和方法 Id //进程的Id ...