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)的更多相关文章

  1. 记录一次配置unix网络编程环境的过程和遇到的问题

    记录一次搭建unix网络编程环境过程中遇到的问题和总结 计算机环境虚拟机 linuxmint-18-xfce-64bit 1.打开unix网络编程.iso 把目录下的文件复制到某一目录,修改权限,可命 ...

  2. unix网络编程环境搭建

    unix网络编程环境搭建 网络编程 环境 1.点击下载源代码 可以通过下列官网中的源代码目录下载最新代码: http://www.unpbook.com/src.html 2.解压文件 tar -xz ...

  3. UNIX网络编程 环境搭建

    配置好动态链接库或者静态链接库 1,下载UNIX网络编程书的头文件及示例源码unpv13e 2    按照readme来编译 Execute the following from the src/ d ...

  4. Unix系统编程()改变信号处置:signal

    Unix系统提供了两种方法来改变信号处置:signal和sigaction.这篇描述的是signal系统调用,是设置信号处理的原始API,所提供的接口比sigaction简单.另一方面,sigacti ...

  5. Unix系统编程()发送信号的其他方式:raise和killpg

    有时,进程需要向自身发送信号,raise 函数就执行了这一任务. #include <signal.h> int raise(int sig); 在单线程程序中,调用raise相当于对ki ...

  6. Unix系统编程()发送信号kill

    与shell的kill命令类似,一个进程能够使用kill系统调用向另一进程发送信号. 之所以选择kill作为术语,因为早期UNIX实现中大多数信号的默认行为是终止进程. #include <si ...

  7. ubuntu14.04下unix网络编程环境的配置

    建议 unpv13e/README看一下,忽略一下内容 ===================================================================== 操作 ...

  8. unix网络编程环境配置程序运行

    1 查看ubuntu版本 cat /etc/issue 2 查看版本 cat /proc/version 3 下载 你可以通过其他方式下载 这里下载好了 文件名为unpv13e 4 开始配置 (1)c ...

  9. ubuntu14.04下unix网络编程 环境的配置

    在ubuntu下 首先:在unpv13e文件加下 ./configure cd lib make cd ../libfree make cd ../liggai make cd .. vim lib/ ...

随机推荐

  1. Qt中截图功能的实现

    提要 需求:载入一张图片并显示,能够放大缩小,能够截取图片的某个矩形并保存. 原以为蛮简单的一个功能,事实上还是有点小复杂. 最简单Qt图片浏览器能够參考Qt自带的Demo:Image Viewer ...

  2. 足球和oracle列(4):巴西惨败于德国,认为,差额RAC拓扑控制!

    足球与oracle系列(4):从巴西慘败于德国,想到,差异的RAC拓扑对照! 前期回想: 本来想说今晚,回头一想,应该是今早第二场半决赛就要开战了!先来回味一下之前的比赛,本届8支小组赛第一名已经所有 ...

  3. hive的非交互模式

    在linux的终端运行:$HIVE_HOME/bin/hive 会进入交互模式: $HIVE_HOME/bin/hive  -e或者-f 是非交互模式 1.非交互模式运行HQL语句 $HIVE_HOM ...

  4. [ACM] hdu 5045 Contest (减少国家Dp)

    Contest Problem Description In the ACM International Collegiate Programming Contest, each team consi ...

  5. [LeetCode]Word Ladder 最短距离字符串转换 (Dijkstra)

    要求最短距离.采纳dijkstra查找节点之间的最短路径. 当心:假设是一个枚举字典22是否元素可以,如果转换,暂停. 提高:每串,带您历数它的字符值事件,对于的长度n一个字符串枚举n*26次要. 设 ...

  6. effective c++ 条款9 do not call virtual function in constructor or deconstructor

    在构造函数中不要调用virtual函数,调用了也不会有预期的效果. 举个例子 class Transaction { public: Transaction() { log(); } ; } clas ...

  7. WPF下的视频录制界面设计

    原文:WPF下的视频录制界面设计 在去年12月份,我曾经写过三篇文章讨论C#下视频录制.播放界面的设计.这三篇文章是:利用C#画视频录制及播放的界面(一) 利用C#画视频录制及播放的界面(二)利用C# ...

  8. POJ 1915-Knight Moves (单向BFS &amp;&amp; 双向BFS 比)

    主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...

  9. Android Application Thread CPU GC Operatiing and OOM Question 0603-随手笔记

    面前app当完成测试,没问题,以完成整个老龄化阶段包含数据收发器,关键在 adb shell top -m 5  我发现我的 app pid 占用  CPU是最多的,事实上我想说写一个app是不难,你 ...

  10. WP8.1开发者预览版本号已知 Bug

    偶的 Lumia 920 已经升级到最新的 8.1 开发者预览版本号,使用中没有发现什么问题. 可能是由于偶玩手机的情况比較少吧!忽然看到 MS 停止此版本号的更新,并说明有非常多的 BUG,偶就郁闷 ...