10–信号
信号是软件中断 ,信号提供了一种处理异步时间的方法 .
例如 : 终端用户键入中断键 ,会通过信号机制停止一个程序 ,或及早终止管道中的下一个程序 .
本章首先对信号进行综述 ,并说明每种信号的一般用法 .然后分析早期实现的问题 .说明问题之后在说明解决方法 .
10.2 信号的概念 .
每个信号都有一个名字 ,这些名字都以3个字符SIG开头 .
在头文件 <signal.h>中信号名都被定义为整数常量(信号编号) . 不存在编号为0的信号 ,kill函数对信号编号0又特殊的应用 .
POSIX.1 将此种信号编号值称为 空信号 .
产生信号的条件 :
1. 当用户按某些中断键时 ,引发终端产生的信号 .
2. 硬件异常产生时 .
3. 进程调用kill(2)函数可将任意信号发送给一个进程或进程组 .
4. 用户可用kill(1)命令可将信号发送给其他信号 .
5. 当检测到某种软件条件已经发生 ,并应将其通知有关进程时也产生信号 .
当某个信号出现时 ,内核按下列三种方式之一进程处理 .
1. 忽略此信号 .
2. 捕捉信号 .
3. 执行系统默认动作 .
10.3函数signal .
*
*函数名 : signal
*功能 : 信号处理 \ 捕捉.
*头文件 : signal.h
*
*原型 : void (*signal(int signo,void (*func)(int)))(int);
*
*返回值 : 成功 : 返回以前的信号处理配置 ; 出错 : SIG_ERR ;
*
*参数 : signo : 信号名 ;
*参数 : func : 是一个带一个整形参数的函数指针 .其值是常量 SIG_IGN,常量SIG_DFL或接到此信号后要调用的函数地址 .
* : 如果指定 SIG_IGN 则向内核表示 忽略此信号 .
* : 如果指定 SIG_DFL 表示接到此信号后 动作是系统默认动作 .
* : 当指定 函数地址 时 ,则信号发生时 ,调用该函数 .
*
10.4不可靠信号 .
信号的不可靠 指 : 信号可能丢失 ,一个信号发生了 ,但进程却可能一直不知道这一点 .
10.5中断系统调用 .
早期unix 的一个特性 : 如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号 ,则系统调用就被终端不在继续执行 .
该系统调用出错返回 errno : EINTR .
10.6不可重入函数 .
10.7SIGCLD语义 .
10.8可靠信号术语和语义 .
当造成信号的事件发生时 , 为进程产生一个信号 ,
事件 : 1.硬件异常 ( 如除以0 ) , 2. 软件条件 ( 如alarm定时器超时 ),
3.终端产生的信号 , 4. 调用 kill函数 .
当一个信号产生时 ,内核 通常在进程表中以某种形式设置一个标志 .
当对信号采取了这种动作时 , 我们说 向进程 递送了 一个信号 .
( 信号是未决的 ): 在信号 产生 和 递送 之间的时间间隔内称 信号是未决的 .
( 保持未决状态 ): 如果进程产生了一个阻塞的信号 ,而对该信号的动作是 系统默认动作 或 捕捉该信号
则为该进程将此信号保持为未决状态 ,直到该进程对此信号解除了阻塞 ,或将其动作改为忽略 .
( 信号屏蔽字 ) : 每个进程都有一个信号屏蔽 ( 字 ) signal mask.它规定了当前要阻塞递送到该进程的信号集 .
10.9函数kill和raise .
kill 函数将信号发送给 进程 或 进程组 . raise 函数则允许进程向自身发送信号 .
10.10 函数alarm 和 pause .
使用alarm可以设置一个定时器 ( 闹钟时间 )在将来的某个时刻该定时器会超时 . 当定时器超时时 ,产生SIG_ALRM信号 .
pause : 使调用进程挂起直到捕捉到一个信号 .
10.11信号集
10.12函数sigprocmask
*
*
*函数名 : sigprocmask
*功能 : 检测或更改 ,或同时进行检测和更改进程信号屏蔽字 .
*头文件 : signal.h
*
*原型 : int sigprocmask(int how,const sigset_t *restrict set,sigset_t *restict oset);
*
*返回值 : 若成功 : 0; 若出错 : -1 ;
*
*参数 : oset : 若oset非空 ,那么进程的当前信号屏蔽字通过oset返回 .
* : set : 其次 , 若set是一个非空指针 ,则参数how指示指示如何修改当前信号屏蔽字 .
* : how : SIG_BLOCK( 或操作 ) : 该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集 .set包含了希望阻塞的附加信号 .
* : SIG_UNBLOCK : 该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集补集的交集 .set 包含了希望解除阻塞的信号 .
* : SIG_SETMASK( 赋值操作 ) 该进程新的信号屏蔽字是set指向的值 .
*
*
*
10.13 函数sigpending
*
*函数名 : sigpending
*功能 : 返回一个信号集 ,对于调用进程而言 ,其中各信号是阻塞不能递送的 ,因而也一定是当前未决的 ,该信号通过set参数返回 .
*头文件 : signal.h
*
*原型 : int sigpending(sigset_t *set);
*
*返回值 : 若成功 : 0; 若出错 : -1 ;
*
*参数 : set : 指向sigset_t信号集数据类型的 指针 .
*
*
10.14sigaction
10.15 sigsetjmp和siglongjmp
10.16函数sigsuspend
*临界资源 : 一次仅允许一个进程使用的资源称为临界资源 : 许多物理设备都属于临界资源 ,如输入机、打印机、磁带机等 .
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问 .
*临界代码 : 每个进程中访问临界资源的那段代码称为临界代码 .
*临界区 : 每个进程中访问临界资源的那段代码称为临界区 (Critical Section) .
*
*
*函数名 : sigsuspend
*功能 : 需要在一个原子操作中 先恢复信号屏蔽字 ,然后使进程休眠 .
*头文件 : signal.h
*
*原型 : int sigsuspend(const sigset_t *sigmask);
*
*返回值 : 返回 -1 并将 errno设为EINTR .
*
*参数 : sigmask : 进程的信号屏蔽字 会被 设置为 sigmask 指向的值 .
*
*
*说明 : 进程的信号屏蔽字设置为sigmask 指向的值 , 在捕捉到一个信号 或 会终止该进程的 信号之前 该进程 会被挂起 ,
* 如果捕捉到一个信号 而且从该信号处理程序 返回 则 sigsuspend 返回 , 并且该信号的屏蔽字设置为 调用suspend之前的 值 .
*
*用途 ? : 如果希望一个信号解除 阻塞 然后pause 以等待 以前被阻塞的 信号发生 。
* : 保护不希望 由信号中断的代码临界区 。
*
10.17 函数 abort
10.18 函数 system
信号是软件中断 ,信号提供了一种处理异步时间的方法 .
例如 : 终端用户键入中断键 ,会通过信号机制停止一个程序 ,或及早终止管道中的下一个程序 .
本章首先对信号进行综述 ,并说明每种信号的一般用法 .然后分析早期实现的问题 .说明问题之后在说明解决方法 .
10.2 信号的概念 .
每个信号都有一个名字 ,这些名字都以3个字符SIG开头 .
在头文件 <signal.h>中信号名都被定义为整数常量(信号编号) . 不存在编号为0的信号 ,kill函数对信号编号0又特殊的应用 .
POSIX.1 将此种信号编号值称为 空信号 .
产生信号的条件 :
1. 当用户按某些中断键时 ,引发终端产生的信号 .
2. 硬件异常产生时 .
3. 进程调用kill(2)函数可将任意信号发送给一个进程或进程组 .
4. 用户可用kill(1)命令可将信号发送给其他信号 .
5. 当检测到某种软件条件已经发生 ,并应将其通知有关进程时也产生信号 .
当某个信号出现时 ,内核按下列三种方式之一进程处理 .
1. 忽略此信号 .
2. 捕捉信号 .
3. 执行系统默认动作 .
10.3函数signal .
*
*函数名 : signal
*功能 : 信号处理 \ 捕捉.
*头文件 : signal.h
*
*原型 : void (*signal(int signo,void (*func)(int)))(int);
*
*返回值 : 成功 : 返回以前的信号处理配置 ; 出错 : SIG_ERR ;
*
*参数 : signo : 信号名 ;
*参数 : func : 是一个带一个整形参数的函数指针 .其值是常量 SIG_IGN,常量SIG_DFL或接到此信号后要调用的函数地址 .
* : 如果指定 SIG_IGN 则向内核表示 忽略此信号 .
* : 如果指定 SIG_DFL 表示接到此信号后 动作是系统默认动作 .
* : 当指定 函数地址 时 ,则信号发生时 ,调用该函数 .
*
10.4不可靠信号 .
信号的不可靠 指 : 信号可能丢失 ,一个信号发生了 ,但进程却可能一直不知道这一点 .
10.5中断系统调用 .
早期unix 的一个特性 : 如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号 ,则系统调用就被终端不在继续执行 .
该系统调用出错返回 errno : EINTR .
10.6不可重入函数 .
10.7SIGCLD语义 .
10.8可靠信号术语和语义 .
当造成信号的事件发生时 , 为进程产生一个信号 ,
事件 : 1.硬件异常 ( 如除以0 ) , 2. 软件条件 ( 如alarm定时器超时 ),
3.终端产生的信号 , 4. 调用 kill函数 .
当一个信号产生时 ,内核 通常在进程表中以某种形式设置一个标志 .
当对信号采取了这种动作时 , 我们说 向进程 递送了 一个信号 .
( 信号是未决的 ): 在信号 产生 和 递送 之间的时间间隔内称 信号是未决的 .
( 保持未决状态 ): 如果进程产生了一个阻塞的信号 ,而对该信号的动作是 系统默认动作 或 捕捉该信号
则为该进程将此信号保持为未决状态 ,直到该进程对此信号解除了阻塞 ,或将其动作改为忽略 .
( 信号屏蔽字 ) : 每个进程都有一个信号屏蔽 ( 字 ) signal mask.它规定了当前要阻塞递送到该进程的信号集 .
10.9函数kill和raise .
kill 函数将信号发送给 进程 或 进程组 . raise 函数则允许进程向自身发送信号 .
10.10 函数alarm 和 pause .
使用alarm可以设置一个定时器 ( 闹钟时间 )在将来的某个时刻该定时器会超时 . 当定时器超时时 ,产生SIG_ALRM信号 .
pause : 使调用进程挂起直到捕捉到一个信号 .
10.11信号集
10.12函数sigprocmask
*
*
*函数名 : sigprocmask
*功能 : 检测或更改 ,或同时进行检测和更改进程信号屏蔽字 .
*头文件 : signal.h
*
*原型 : int sigprocmask(int how,const sigset_t *restrict set,sigset_t *restict oset);
*
*返回值 : 若成功 : 0; 若出错 : -1 ;
*
*参数 : oset : 若oset非空 ,那么进程的当前信号屏蔽字通过oset返回 .
* : set : 其次 , 若set是一个非空指针 ,则参数how指示指示如何修改当前信号屏蔽字 .
* : how : SIG_BLOCK( 或操作 ) : 该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集 .set包含了希望阻塞的附加信号 .
* : SIG_UNBLOCK : 该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集补集的交集 .set 包含了希望解除阻塞的信号 .
* : SIG_SETMASK( 赋值操作 ) 该进程新的信号屏蔽字是set指向的值 .
*
*
*
10.13 函数sigpending
*
*函数名 : sigpending
*功能 : 返回一个信号集 ,对于调用进程而言 ,其中各信号是阻塞不能递送的 ,因而也一定是当前未决的 ,该信号通过set参数返回 .
*头文件 : signal.h
*
*原型 : int sigpending(sigset_t *set);
*
*返回值 : 若成功 : 0; 若出错 : -1 ;
*
*参数 : set : 指向sigset_t信号集数据类型的 指针 .
*
*
10.14sigaction
10.15 sigsetjmp和siglongjmp
10.16函数sigsuspend
*临界资源 : 一次仅允许一个进程使用的资源称为临界资源 : 许多物理设备都属于临界资源 ,如输入机、打印机、磁带机等 .
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问 .
*临界代码 : 每个进程中访问临界资源的那段代码称为临界代码 .
*临界区 : 每个进程中访问临界资源的那段代码称为临界区 (Critical Section) .
*
*
*函数名 : sigsuspend
*功能 : 需要在一个原子操作中 先恢复信号屏蔽字 ,然后使进程休眠 .
*头文件 : signal.h
*
*原型 : int sigsuspend(const sigset_t *sigmask);
*
*返回值 : 返回 -1 并将 errno设为EINTR .
*
*参数 : sigmask : 进程的信号屏蔽字 会被 设置为 sigmask 指向的值 .
*
*
*说明 : 进程的信号屏蔽字设置为sigmask 指向的值 , 在捕捉到一个信号 或 会终止该进程的 信号之前 该进程 会被挂起 ,
* 如果捕捉到一个信号 而且从该信号处理程序 返回 则 sigsuspend 返回 , 并且该信号的屏蔽字设置为 调用suspend之前的 值 .
*
*用途 ? : 如果希望一个信号解除 阻塞 然后pause 以等待 以前被阻塞的 信号发生 。
* : 保护不希望 由信号中断的代码临界区 。
*
10.17 函数 abort
10.18 函数 system
10.19 函数 sleep nanosleep clock_nanosleep
待补充 。。。