信号(2)

sigaction函数

sigaction函数的功能是检查或改动与制定信号相关联的处理动作。此函数代替了signal函数。

#include <signal.h>

int sigaction(int signum, const structsigaction *act, struct sigaction *oldact);

此函数使用下列结构:

struct sigaction {

void     (*sa_handler)(int);

void     (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t   sa_mask;

int        sa_flags;

void     (*sa_restorer)(void);

};

返回值:若成功则返回0,如出错则返回-1。

当中參数,signum是要检測或改动其详细动作的信号编号。若oact指针非空,则将把原先对该信号的动作写到它指向的位置。若act是空指针,则sigaction函数就不须要再做其它设置了,否则将在该參数中设置对指定信号的动作。

在參数act指向的sigaction结构中,sa_handler是一个函数指针,它指向接收信号sig时将被调用的信号处理函数。它相当于前面见到的传递函数signal的參数func。我们能够将sa_handler字段设置为特殊SIG_IGN和SIG_DFL,它们分别表示信号将被忽略或把对该信号的处理方式恢复为默认动作。

sa_mask字段指定了一个信号集,在调用sa_handle所指向的信号处理函数之前,该信号集将被增加到进程的信号屏蔽字中。这是一组将被堵塞且不会被传递给该进程的信号。设置信号屏蔽字能够防止前面看到的信号在它的处理函数还未执行结束时就被接收到的情况。

以下的程序能够实现signal函数。

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 {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}

sigsetjmp和siglongjmp

在信号处理中进行非局部转移时,应当使用这两个函数。

#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, intsavesigs);

void siglongjmp(sigjmp_buf env, int val);

这两个函数与setjmp和longjmp之间的唯一差别是sigsetjmp添加了一个參数。假设savesigs非0,则sigsetjmp在env中保存了进程的当前信号屏蔽字。调用siglongjmp时,假设带非0 savesigs的sigsetjmp调用已经保存了env,则siglongjmp从当中恢复保存的信号屏蔽字。

sigsuspend函数

#include<signal.h>

intsigsuspend(const sigset_t *mask);

将进程的信号屏蔽字设置为mask指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。假设捕捉到一个信号并且从该信号处理程序返回,则sigsuspend返回,并且将该进程的信号屏蔽字设置为调用sigsuspend之前的值。

absorb函数

#include<stdlib.h>

voidabort(void);

该函数使异常终止。此函数将SIGABRT信号发送给调用进程。调用abort将向主机环境传递一个为成功终止的通知,其方法是调用raise函数。abort将会冲洗所以打开的流;确保进程对此信号不堵塞,不理会进程对此信号的堵塞。

下面是POSIX.1中abort函数的实现:

#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h> void
abort(void) /* POSIX-style abort() function */
{
sigset_t mask;
struct sigaction action; /*
* Caller can't ignore SIGABRT, if so resetto default.
*/
sigaction(SIGABRT, NULL, &action);
if (action.sa_handler == SIG_IGN) {
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL);
}
if (action.sa_handler == SIG_DFL)
fflush(NULL); /* flush all open stdio streams */
/*
* Caller can't block SIGABRT; make sureit's unblocked.
*/
sigfillset(&mask);
sigdelset(&mask, SIGABRT); /* mask has only SIGABRT turned off */
sigprocmask(SIG_SETMASK, &mask, NULL);
kill(getpid(), SIGABRT); /* send the signal */ /*
* If we're here, process caught SIGABRTand returned.
*/
fflush(NULL); /* flush all open stdio streams*/
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL); /* reset to default */
sigprocmask(SIG_SETMASK, &mask,NULL); /* just in case ... */
kill(getpid(), SIGABRT); /* and one more time */
exit(1); /* this should never be executed ... */
}

sleep函数

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

此函数使调用进程被挂起,直到满足下面条件之中的一个:

1.      已经过了seconds所指定的墙上时钟时间

2.      调用进程捕捉到一个信号并从信号处理程序返回

作业控制信号

6个与作业控制有关的信号:

SIGCHLD                    子进程已停止或终止

SIGCONT                    假设进程已停止,则使其继续执行

SIGSTOP                     停止信号

SIGTSTP                      交互式停止信号

SIGTTIN                      后台进程组成员读控制终端

SIGTTOU                    后台进程组写到控制终端

当键入挂起字符键(一般是ctrl+Z)时,SIGTSTP被送至前台进程组的全部进程。当我们通知shell在前台或后台恢复执行一个作业时,shell向该作业中的全部进程发送SIGCONT信号。

Linux/UNIX之信号(2)的更多相关文章

  1. Linux/UNIX之信号(1)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/walkerkalr/article/details/24462723 信号(1) 信号是软件中断.每 ...

  2. Linux/Unix监控其他用户和信号

    --Linux/Unix监控其他用户和信号 ------------------------------------------------------2013/10/27   查看有哪些用户登录 w ...

  3. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

  4. [转]Linux进程间通信——使用信号

    转载于:http://blog.csdn.net/ljianhui/article/details/10128731         经典!!! Linux进程间通信——使用信号 一.什么是信号 用过 ...

  5. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  6. 练习--LINUX进程间通信之信号SIGNAL

    同样的,信号也不要太迷信可靠信号及不及靠信号,实时或非实时信号. 但必须要了解这些信号之间的差异,函数升级及参数,才能熟练运用. ~~~~~~~~~~~~~~~~ 信号本质 信号是在软件层次上对中断机 ...

  7. 编写Linux/Unix守护进程

    原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开 ...

  8. 转:linux/unix命令行终端的光标及字符控制快捷键

    from:http://linux.chinaunix.net/techdoc/system/2007/11/23/973027.shtml 在使用linux/unix的命令行终端时,有时候会碰到键盘 ...

  9. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

随机推荐

  1. TIA Portal V12不能添加新的CPU

    4核AMD 740,10G内存,Win7 X64,打开TIA Portal V12,依旧慢如牛,鼠标指针转啊转,TIA窗口写着 无响应... 真没志气,STM32要是玩转了,坚决不用这老牛. 上图为正 ...

  2. poj 3466 A Simple Problem with Integers

    题目链接:http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 思路 ...

  3. (08)DBA写给开发的索引经验

          索引可是个大事情,翻开任意一本数据库调优的书,索引都会占到比较大的篇幅.这是个人人都很重视的问题,可往往起始阶段还好,但数据库到最后常常还是会陷入由索引起的性能怪圈中.特别是在上线运行过一 ...

  4. eclipse升级后Android使用JAR报错

    升级ADT22以后,老项目编译时后遇到 NoDefFoundClassError  这个错误,因为项目中使用了jar文件. 遇到此问题的解决步骤: 1.项目根目录下建立 libs ,并将jar文件移入 ...

  5. Qt中用正則表達式来推断Text的语种,主要通过推断unicode的编码范围

    QString MainWindow::ParseLanguage(QString Text) {     if(Text.length()<=0)     {         return & ...

  6. javascript中apply和eval结合的强大用法

        eval是一个函数,可以接受一个参数,这个参数可以作为js语句被解释性的执行,利用这个特性,eval和apply结合起来,可以大大简化代码  如下例子 <a class="cl ...

  7. mmtests使用简介

    1.简介 mmtests是一个可配置的测试套件,可以被MM开发者用来进行一个常规测试.理想情况下,它可以与LTP,xfstests等测试工具结合起来实现自动化测试. 2.软件组织 run-mmtest ...

  8. NYOJ 623 A*B ProblemII

    A*B Problem II 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描写叙述 ACM的C++同学有好多作业要做,最头痛莫过于线性代数了.由于每次做到矩阵相乘的时候,大 ...

  9. 熬之滴水穿石:JSP--HTML中的JAVA代码(6)

                                                                       39--JSTL 在JSP编码中需考虑的一种方法,因为这种方法可以 ...

  10. 文顶顶 iOS开发UI篇—UITabBarController简单介绍 iOS开发UI篇—UITabBarController简单介绍

    一.简单介绍 UITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型的例 ...