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. Google Maps Android API v2 (2)- 地图对象

    地图对象 Android的谷歌地图API允许你在你的Andr​​oid应用程序中显示谷歌地图.在谷歌地图移动(GMM)的应用程序,你看到的地图,这些地图具有相同的外观和API暴露出许多相同的功能.GM ...

  2. 4pdf

    http://www.cnblogs.com/haocool/archive/2013/03/16/2962547.html

  3. 程序员之---C语言细节22(函数返回指针注意事项&lt;悬空指针&gt;、查看进程能够分配的内存大小)

    主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static ...

  4. ASF(传感器)

    版权声明:曾经的Blog文章合并.原创作品,谢绝转载.否则将追究法律责任. SensorManager类:用于创建sensor service的实例.该类提供了非常多 用于訪问和枚举传感器,注冊和注销 ...

  5. Sql Server远程查询db 表中的数据,以本地

    step 1: sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'Ad Hoc Distributed Queri ...

  6. 【Spring】Spring学习笔记-01-入门级实例

    听说当前Spring框架很流行,我也准备好好学学Spring开发,并将学习的过程和大家分享,希望能对志同道合的同学有所帮助. 以下是我学习Spring的第一个样例. 1.Spring开发环境的搭建 我 ...

  7. 在C#主线程和子线程将数据传递给对方如何实现

    在C#中主线程和子线程怎样实现互相传递数据 老帅 在C#中创建线程Thread时,能够有多种方法,而主线程和子线程之间又怎样实现互相传递数据,每种创建方法传递參数的效果是不同的,逐一看一下:  一.不 ...

  8. Lua中的weak表——weak table(转)

    弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...

  9. 什么是Cyclomatic Complexity(圈复杂度)?

    Campwood Software SourceMonitor Version 3.5 The freeware program SourceMonitor lets you see inside y ...

  10. Scilab 的画图函数(1)

    Scilab 的画图函数 plot 函数 最主要的是 plot 函数,与 matlab 中的plot 函数类似. xdata = linspace(1,10,50); ydata = sin(xdat ...