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. 游戏碰撞OBB算法(java代码)

    业务需求      游戏2D型号有圆形和矩形,推断说白了就是碰撞检测 :      1.圆形跟圆形是否有相交      2.圆形跟矩形是否相交       3.矩形和矩形是否相交           ...

  2. MyEclipse建立JVM内存大小

    1.你为什么要设置JVM它的内存大小? 因为假定程序执行过JVM默认的内存大小.他们不会报告传说中的内存溢出异常. Exception in thread "main" java. ...

  3. debain install scim

    1. su input root pwd 2. apt-cache search scim apt-get install scim apt-cache search scim-pinyin apt- ...

  4. projecteuler----&gt;problem=14----Longest Collatz sequence

    title: The following iterative sequence is defined for the set of positive integers: n n/2 (n is eve ...

  5. rac 中节点的vip在该节点启动不了,在其它节点正常启动。

    本实验是在虚拟机中! 与实验同样的问题:http://blog.csdn.net/wanghui5767260/article/details/38850335 问题描写叙述: 节点1.节点2和节点3 ...

  6. Cocos发展Visual Studio下一个libcurl图书馆开发环境的搭建

    我们解释win32在Visual Studio下一个libcurl图书馆开发环境的搭建.Cocos2d-x发动机实际上与Win32在访问libcurl库.Cocos2d-x 3.x在libcurl库文 ...

  7. Twitter实时搜索系统EarlyBird

    twitter要存档tweet采用lucene做全量指数,新发型是实时索引推文.检索实时(10在几秒钟内指数).实时索引和检索系统,称为EarlyBird. 感觉写更清晰,简洁,这个信息是真实的,只有 ...

  8. MAC随机修改批处理

    原文:MAC随机修改批处理 @echo off mode con cols=70 lines=20 title MAC随机修改工具 color 3F setlocal enabledelayedexp ...

  9. web引用和服务引用

    原文:web引用和服务引用 在VS2010环境下开发C#的winform程序或者WPF时,会碰到调用web引用的问题. 1.添加一个服务引用时,会在app.config里生成basicHttpBind ...

  10. ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件

    原文:ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件 第二章 继承于WebControl的自定义控件 到现在为止,我已经写了三篇关于自定义控件开发的文章,很感谢大家的支 ...