优秀是一种习惯,生命是一个过程,不求进步很大,只求每天进步一点点,无为之道!

《unix环境高级编程》通读学习笔记(二)(第10章)

上一篇 / 下一篇  2007-12-13 20:33:59 / 个人分类:UNIX 编程学习

 

《unix环境高级编程》通读学习笔记(二)(第10章)

 第10章 信号 

10.1 引言 

信号是软件中断。它提供了一种处理异步事件的方法。

10.2 信号的概念 

字符SIG开头 头文件<signal.h>中

产生一个信号的条件:

1.用户按某些终端键

2.硬件异常产生信号

3.进程用kill(2)函数可将信号发送给令一个进程或进程组

4.用户可用kill(1)命令将信号发送给其他进程

5.当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号

信号出现时的三种操作方式:

1.忽略此信号

2.捕捉信号

3.执行系统默认动作

表10-1 UNIX信号

10.3 signal函数 

signal函数为信号处理程序(signal handler)或信号捕捉函数(signal-catching function)

————————————————————————————————————————————————————

#include <signal.h>

void (*signal(int signo,void (*func)(int)))(int);

                                            返回:成功则为以前的信号处理配置,若出错则为SIG_ERR

————————————————————————————————————————————————————

10.4 不可靠的信号 

10.5 中断的系统调用 

系统调用分为两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用。

表10-2 几种信号实现所提供的功能

10.6 可再入函数 

进程捕捉到信号并继续执行时,首先执行该信号处理程序中的指令。如果从信号处理程序返回,则继续执行在捕捉到信号时进程正在执行的正常指令序列。

如果进程正在执行某函数,由于捕捉到信号插入执行信号处理程序,其中又调用该函数,则可能会出错。所以引入了可再入函数的概念。

表10-3 信号处理程序中可以调用的可再入函数

10.7 SIGCLD语义 

SIGCLD是系统V的一个信号名,它不同于其他信号。如果用signal或sigset设置信号配置,则SVR4存在兼容性限制。所以务必了解你所用的系统中SIGCHLD信号的语义。

10.8 可靠信号术语和语义 

当造成信号的事件发生时,为进程产生一个信号,内核在进程表中设置一个标志,这个动作称之为向一个进程递送了一个信号。在信号产生(generation)和递送(delivery)之间的时间间隔内,称信号未决(pending)。

当递送一个原来北阻塞的信号给进程时,而不是在产生该信号时,内核才决定对它的处理方式。于是进程在信号递送给它之前仍可改变对它的动作。

10.9 kill 和raise函数 

kill函数将信号发送给进程或进程组。raise函数则允许进程向自身发送信号。

———————————————————————————————————————————————————

#include <sys/ttpes.h>

#include <signal.h>

int kill(pid_t pid,int signo);

int raise(int signo);

                                 两个函数返回:若成功则为0,若出错则为-1

———————————————————————————————————————————————————

进程将信号发送给其他进程需要许可权。

10.10 alarm和 pause函数 

alarm函数可以设置一个时间值(闹钟时间),当所设置的时间值被超过后,产生SIGALRM信号。

————————————————————————————————————————————————————

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

                                    返回:0或以前设置的闹钟实践的余留秒数

————————————————————————————————————————————————————

每个进程只能有一个闹钟时间。大多数是使用闹钟的进程捕捉此信号。

pause函数使调用进程挂起直至捕捉到一个信号。

————————————————————————————————————————————————————

#include <unistd.h>

int pause(void);

                                   返回:-1,errno设置为EINTR

————————————————————————————————————————————————————

只有执行了一个信号处理程序并从其返回时,pause才返回。

10.11 信号集 

能表示多个信号-信号集(signal set)的数据类型。

数据类型sigset_t包含一个信号集。五个处理信号集的函数:

————————————————————————————————————————————————————

#include <signal.h>

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set,int signo);

int sigdelset(sigset_t *set,int signo);

                                           四个函数返回:若成功则为0,若出错则为-1

int sigismember(const sigset_t *set,int signo);

                                           返回:若真则为1,若假则为0

————————————————————————————————————————————————————

函数sigemptyset初始化由set指向的信号集,使排除其中所有信号。

函数sigfillset初始化由set指向的信号集,使其包括所有信号。

所有应用程序在使用信号集前,要对该信号集调用sigemptyset或sigfillset一次。

函数sigaddset将一个信号添加到现存集中,sigdelset则从信号集中删除一个信号。对所有以信号集作为参数的函数,都向其传送信号集地址。

10.12 sigprocmask 函数 

一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集。调用函数sigprocmask可以检测或更改(或两者)进程的信号屏蔽字。

————————————————————————————————————————

# include <signal.h>

int sigprocmask(int h o w, const sigset_t *s e t, sigset_t *o s e t) ;

返回:若成功则为0,若出错则为-1

————————————————————————————————————————

10.13 sigpending函数 

sigpending返回对于调用进程被阻塞不能递送和当前未决的信号集。该信号集通过set参数返回。

——————————————————————————————————————————

#include <signal.h>

int sigpending(sigset_t *s e t) ;

返回:若成功则为0,若出错则为-1

——————————————————————————————————————————

10.14 sigaction函数 

sigaction函数的功能是检查或修改(或两者)与指定信号相关联的处理动作。此函数取代了UNIX早期版本使用的signal函数。

————————————————————————————————————

#include <signal.h>

int sigaction(int signo, const struct sigaction *a c t,

struct sigaction *oact) ;

返回:若成功则为0,若出错则为- 1

————————————————————————————————————

struct sigaction {

void       (*sa_handler)(); /* addr of signal handler,

or SIG_IGN, or SIG_DFL */

sigset_t sa_mask;           /* additional signals to block */

int        sa_flags;       /* signal options, Table 10-5 */

} ;

表10-5  信号处理的选择项标志( sa_flags)

10.15 sigsetjmp 和siglongjmp函数 

在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。

POSIX.1定义了两个新函数sigsetjmp和siglongjmp。在信号处理程序中作非局部转移时应当使用这两个函数。

——————————————————————————————————

#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, int savemask) ;

返回:若直接调用则为0,若从siglongjmp调用返回则为非0

void siglongjmp(sigjmp_buf env, int val)

——————————————————————————————————

10.16 sigsuspend函数 

一个原子操作中实现恢复信号屏蔽字,然后使进程睡眠,这种功能是由sigsuspend函数所提供的。

——————————————————————————————————

#include <signal.h>

int sigsuspend(const sigset_t *sigmask) ;

返回:-1, errno设置为EINTR

——————————————————————————————————

10.17 abort函数 

abort函数的功能是使程序异常终止。

——————————————————————————————————

#include <stdlib.h>

void abort(void);

此函数不返回

——————————————————————————————————

此函数将SIGABRT信号发送给调用进程。进程不应忽略此信号。

ANSI C要求若捕捉到此信号而且相应信号处理程序返回, abort仍不会返回到其调用者。

10.18 system 函数 

POSIX.2要求system忽略SIGINT和SIGQUIT,阻塞SIGCHLD。

因为由system执行的命令可能是交互作用命令,以及因为system的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system的调用者就不应接收这两个终端产生的信号。

system的返回值是shell的终止状态,它不总是执行命令字符串进程的终止状态。

10.19 sleep函数 

——————————————————————————————————

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

返回:0或未睡的秒数

——————————————————————————————————

此函数使调用进程被挂起直到:

(1) 已经过了seconds所指定的墙上时钟时间,或者

(2) 该进程捕捉到一个信号并从信号处理程序返回。

sleep可以用alarm函数实现,但这并不是必需的。如果使用alarm,则这两个函数之间可以有交互作用。

10.20 作业控制信号 

在表10-1中有六个POSIX.1认为是与作业控制有关的信号。

SIGCHLD  子进程已停止或终止。

SIGCONT  如果进程已停止,则使其继续运行。

SIGSTOP  停止信号(不能被捕捉或忽略)。

SIGTSTP  交互停止信号。

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

SIGTTOU  后台进程组的成员写控制终端。

大多数应用程序并不处理这些信号——交互式shell通常做处理这些信号的所有工作

10.21 其他特征 


TAG:

 

评分:0

我来说两句

日历

« 2024-05-18  
   1234
567891011
12131415161718
19202122232425
262728293031 

我的存档

数据统计

  • 访问量: 7651
  • 日志数: 10
  • 书签数: 4
  • 建立时间: 2007-12-10
  • 更新时间: 2007-12-20

RSS订阅

Open Toolbar