signal函数的使用
- 格式:doc
- 大小:24.00 KB
- 文档页数:5
signal函数用法信号(signal)函数是C语言中处理程序异常的一种机制,它允许程序在发生某些特定事件时,例如运行时错误、非法访问等,采取相应的措施进行处理。
本文将详细介绍信号函数的用法,帮助您更好地理解和应用该机制。
一、信号函数的定义在C语言中,信号函数是通过`signal()`函数来设置的。
该函数的基本语法如下:```c#include <signal.h>void (*signal(int sig, void (*func)(int)))(int);```其中,`sig`参数指定要处理的信号类型,`func`参数是一个回调函数,当指定信号发生时,会调用该函数来处理。
`signal()`函数返回一个指向被设置的信号处理函数的指针。
二、信号函数的处理方式信号函数可以接受三种不同的处理方式:1. 忽略信号:使用`signal()`函数将信号设置为忽略,即不进行任何处理。
2. 默认处理方式:使用`signal()`函数将信号设置为默认处理方式,即由操作系统默认处理该信号。
3. 自定义处理方式:使用`signal()`函数将信号设置为自定义处理方式,即由用户自定义的处理函数来处理该信号。
三、信号函数的回调函数当信号发生时,会调用用户自定义的处理函数来处理。
该处理函数的参数为一个整数(sig),表示发生的是哪种类型的信号。
处理函数可以执行一些清理操作(如释放资源、关闭文件等),并返回一个值。
通常情况下,返回值为0表示成功处理了信号。
四、使用示例下面是一个使用信号函数的示例代码,演示如何捕获和处理特定类型的信号:```c#include <stdio.h>#include <signal.h>#include <unistd.h>void signal_handler(int sig) {switch(sig) {case SIGINT: // 处理SIGINT信号(Ctrl+C)printf("Caught SIGINT!\n");// 在这里执行清理操作,如关闭文件、释放资源等break;default:printf("Unknown signal: %d\n", sig);break;}}int main() {// 将SIGINT信号设置为自定义处理方式,并指定signal_handler函数为处理函数signal(SIGINT, signal_handler);printf("Press Ctrl+C to exit...\n");while(1) {sleep(1);}return 0;}```在上述示例中,当程序接收到SIGINT信号(通常由Ctrl+C产生)时,会调用自定义的处理函数`signal_handler()`来处理该信号。
Signal函数Signal函数:这个函数是⼀种系统调⽤,就是告诉系统发⽣中断的时候⽤该⼲嘛。
第⼀个参数就是信号的编号,第⼆个参数就是信号的指针。
原型:#include <signal.h>void ( *signal(int sig, void (*handler)(int)) ) (int);第⼀个参数sig:要传⼊需要修改处理函数的信号编号。
第⼆个参数:是⼀个⽆返回值类型,接受⼀个int形参的函数指针,指向对sig信号的新处理函数。
第⼆个参数有三种选择:1.⾃⼰定义的信号处理函数2.传⼊SIG_DEF表⽰将之前signal所改变的信号处理⽅式还原3.传⼊SIG_IGN表⽰处理⽅式为忽略信号,内核会直接将信号丢弃,不会传递给进程SIGHUP 挂起信号SIGINT 中断信号SIGQUIT 退出信号SIGILL ⾮法指令SIGTRAP 跟踪/断点中断SIGABRT 放弃SIGFPE 浮点异常SIGKILL 删除(不能捕获或者忽略)SIGBUS 总线错误SIGEGV分段错误SIGSYS 系统调⽤错误参数SIGPIPE 管道错误SIGALRM 闹钟SIGTERM 软件终⽌SIGUSR1 ⽤户信号1SIGUSR2 ⽤户信号2SIGCHLD⼦状态改变SIGPWR 功能失败/重新启动SIGWINCH 窗⼝⼤⼩改变SIGUGR 紧急⽹络界⾯接⼝条件SIGPOLL 可修改的事件发⽣SIGSTOP 停⽌(不能捕获或忽略)SIGTSTP ⽤户停⽌请求SIGCONT停⽌的进程继续进⾏signal(SIGHUP, SIG_IGN);。
C语⾔中signal函数简介及使⽤signal.h是C标准函数库中的信号处理部分,定义了程序执⾏时如何处理不同的信号。
信号⽤作进程间通信,报告异常⾏为(如除零)、⽤户的⼀些按键组合(如同时按下Ctrl与C键,产⽣信号SIGINT)。
C++中的对应头⽂件是csignal。
C语⾔标准定义了6个信号,都定义在signal.h头⽂件中:(1). SIGABRT:程序异常中⽌,如调⽤abort函数。
(2). SIGFPE:算术运算出错,如除数为0或溢出。
(3). SIGILL:⾮法函数映像,如⾮法指令。
(4). SIGINT:交互的⽤户按键请求,如同时按下Ctrl+C键。
(5). SIGSEGV:⽆效内存访问,段错误。
(6). SIGTERM:程序的中⽌请求。
signal.h可能还定义了其它信号,这依赖于具体实现。
例如,类Unix系统还定义了15个以上的信号。
Visual C++的C标准库只⽀持C语⾔标准规定的6个信号,即对信号处理只提供最⼩的⽀持。
signal函数:该函数设置⼀个函数(回调函数)来处理捕获到异常信号时需要执⾏的操作,其函数声明⽅式如下:// Type of a signal handlertypedef void (*__sighandler_t)(int);__sighandler_t signal(int __sig, __sighandler_t __handler);下⾯是测试代码:#include "signal.hpp"#include <signal.h>#include <string>#include <thread>#include <chrono>namespace signal_ {namespace {bool flag = true;void process_exit(int sig){switch (sig) {case SIGINT:fprintf(stderr, "process exit: SIGINT: value: %d\n", sig);break;case SIGFPE:fprintf(stderr, "process exit: SIGFPE: value: %d\n", sig);break;case SIGABRT:fprintf(stderr, "process exit: SIGABRT: value: %d\n", sig);break;case SIGILL:fprintf(stderr, "process exit: SIGILL: value: %d\n", sig);break;case SIGSEGV:fprintf(stderr, "process exit: SIGSEGV: value: %d\n", sig);break;case SIGTERM:fprintf(stderr, "process exit: SIGTERM: value: %d\n", sig);break;break;default:fprintf(stderr, "process exit: value: %d\n", sig);break;}flag = false;}void wait_ctrl_c(){while (flag) {std::this_thread::sleep_for(std::chrono::seconds(2)); fprintf(stdout, "please press to exit: Ctrl + c ... \n"); }}void signal_type(){signal(SIGINT, process_exit);signal(SIGFPE, process_exit);signal(SIGILL, process_exit);signal(SIGABRT, process_exit);signal(SIGSEGV, process_exit);signal(SIGTERM, process_exit);}void signal_sigill(int){fprintf(stdout, "caught SIGILL signal\n");}void signal_sigterm(int){fprintf(stdout, "caught SIGTERM signal\n");}} // namespaceint test_signal_SIGINT(){signal_type();std::thread th(wait_ctrl_c);th.join();return 0;}int test_signal_SIGILL(){//signal_type();if (signal(SIGILL, signal_sigill) == SIG_ERR) {fprintf(stdout, "cannot handle SIGILL\n");} else {fprintf(stdout, "yyyyy\n");}return 0;}int test_signal_SIGFPE(){signal_type();int a = 1, b = 0, c;c = a / b;fprintf(stdout, "c = %d\n", c);return 0;}int test_signal_SIGSEGV(){signal_type();int a[3] = {0};fprintf(stdout, "a[3] = %d\n", a[-1111111]);return 0;}int test_signal_SIGTERM(){//signal_type();if (signal(SIGTERM, signal_sigterm) == SIG_ERR) {fprintf(stdout, "cannot handle SIGTERM\n");} else {fprintf(stdout, "xxxxx\n");}return 0;}int test_signal_SIGABRT(){signal_type();abort();return 0;}} // namespace signal_测试test_signal_SIGINT时的输出结果如下:。
在Matlab中,signal的应用是非常广泛且重要的,它涵盖了信号处理、通信系统、控制系统等领域,对于工程技术人员而言,熟练掌握signal的用法是至关重要的。
在本文中,我将从信号处理的基础概念开始,逐步深入探讨Matlab中signal的用法,并结合个人观点和理解,为您全面解读。
1. 信号处理基础概念在信号处理中,信号是指传递信息的载体,可以是声音、图像、视频等形式。
信号处理的基本任务是对信号进行采集、分析和处理,以获取所需的信息。
在Matlab中,通过signal processing toolbox提供了丰富的工具和函数,可以帮助工程师完成各种信号处理任务。
从最基本的信号读取和显示,到信号滤波、频谱分析,再到高级的信号重构和处理,Matlab都提供了强大的支持。
2. 信号处理工具箱Matlab的signal processing toolbox提供了一系列用于信号处理的函数和工具,其中包括时域分析、频域分析、滤波器设计、谱估计等方面的功能。
在使用这些工具时,我们可以根据具体的需求选择合适的函数和方法,进行灵活的信号处理操作。
Matlab的signal processing toolbox还提供了丰富的示例和文档,可以帮助工程师快速上手,并更深入地理解每个函数的原理和用法。
3. 信号处理示例下面我将通过示例演示Matlab中signal的用法,以便更直观地展现其功能和特点。
我们将从最基本的信号读取和显示开始,逐步进行频谱分析、滤波处理,最终实现信号的重构和处理。
通过这些示例,您可以更直观地感受到Matlab在信号处理领域的强大功能和灵活性。
4. 个人观点和理解在我看来,Matlab中signal的用法不仅可以帮助工程师完成各种信号处理任务,还可以帮助他们更深入地理解信号处理的原理和方法。
通过Matlab的强大工具和丰富函数,工程师可以快速高效地完成各种信号处理任务,提高工作效率。
Matlab提供的示例和文档也为工程师提供了学习和研究的资源,可以帮助他们更深入地理解信号处理领域的知识和技术。
singal函数signal()函数是C语言中的一个系统调用函数,用来设置对特定信号的处理方式。
在程序中使用signal()函数可以捕获并处理指定信号,具体操作为对指定信号指定一个处理函数,当程序接收到指定信号时,就会执行对应的处理函数。
signal()函数的原型如下:```cvoid (*signal (int signum, void (*handler)(int)))(int);```其中,signum是指定信号的编号,handler是一个信号处理函数的指针。
signal()函数返回的是一个指向之前信号处理函数的指针,如果返回的是SIG_ERR(-1),表示信号函数设置失败。
C语言中定义了一些常见的信号符号常量,如:- SIGABRT:终止信号,由程序调用abort()函数触发。
- SIGALRM:闹钟信号,由alarm()函数设置的定时器时间到达时产生。
- SIGINT:中断信号,由终端键盘产生,通常是Ctrl+C键。
-SIGSEGV:段错误信号,由程序访问非法内存时触发。
-SIGFPE:浮点异常信号,由程序发生浮点异常时触发。
下面是一个示例程序,演示了使用signal()函数来捕获并处理SIGINT信号:```c#include<stdio.h>#include<signal.h>void signal_handler(int signum)printf("Received signal %d\n", signum);//恢复SIGINT默认处理方式signal(SIGINT, SIG_DFL);int mai//注册信号处理函数signal(SIGINT, signal_handler);while (1)printf("Running...\n");sleep(1);}return 0;```在上面的程序中,首先定义了一个信号处理函数signal_handler (),当程序接收到SIGINT信号时,该函数会被执行。
python signal库的用法`signal`库是Python中用于处理信号的模块。
信号是在操作系统中发生的事件,如按下Ctrl+C、进程终止等,可以用来通知进程发生了某个事件。
`signal`库提供了一些函数来处理和控制信号。
下面是`signal`库的一些常用函数和用法:### 注册信号处理函数`signal.signal(signalnum, handler)` 用于注册一个信号处理函数。
参数:-`signalnum`:信号编号,可以使用内置常量(如`signal.SIGINT`)或整数表示。
常见的信号编号包括:- `signal.SIGINT`:终端中断信号(通常是按下Ctrl+C)。
- `signal.SIGTERM`:程序终止信号。
- `signal.SIGUSR1`:用户自定义信号1。
- `signal.SIGUSR2`:用户自定义信号2。
-等等,完整的信号列表请参考Python官方文档。
-`handler`:信号处理函数,当接收到指定信号时会调用该函数。
函数接受两个参数,分别是信号编号和当前帧对象。
示例:```pythonimport signaldef handler(signum, frame):print("Received signal:", signum)# 注册SIGINT信号处理函数signal.signal(signal.SIGINT, handler)# 程序会等待SIGINT信号print("Waiting for signal...")signal.pause() # 暂停程序执行,等待信号处理函数被调用```### 忽略信号`signal.signal(signalnum, signal.SIG_IGN)` 可以忽略指定的信号。
示例:```pythonimport signal# 忽略SIGINT信号signal.signal(signal.SIGINT, signal.SIG_IGN)# 程序不会对SIGINT信号做出任何响应```### 暂停程序执行`signal.pause()` 用于暂停程序执行,等待信号处理函数被调用。
Linux 中的signal 函数用于处理进程接收到的信号。
signal 函数有两个参数:sig 和func。
sig 参数表示将要处理哪种类型的信号,而func 参数是一个函数指针,用来指定信号的处理函数。
当进程接收到sig 那个类型的信号后,就会调用func 指针指向的函数。
以下是linux signal 使用的详细步骤:1. 包含头文件:在使用signal 函数之前,需要包含相应的头文件。
在C 语言中,需要包含`signal.h`头文件。
2. 定义信号处理函数:需要定义一个函数,用于处理接收到的信号。
这个函数的原型通常为`void (*func)(int)`,其中int 类型的参数表示信号的整数值。
3. 调用signal 函数:使用signal 函数设置信号处理函数。
signal 函数的调用格式为`signal(sig, func)`,其中sig 表示要处理的信号类型,func 表示信号处理函数的函数指针。
4. 编写主程序:在主程序中,使用`while`或`for`循环等方法,等待信号的到来。
当接收到信号时,程序会自动调用已设置的信号处理函数。
5. 处理信号:在信号处理函数中,根据信号类型和需求,进行相应的处理。
例如,当接收到SIGINT(Ctrl+C)信号时,可以执行退出程序的操作。
6. 释放资源:在程序结束时,使用`sigaction`函数撤销信号处理函数的设置,以释放资源。
以下是一个简单的示例,演示了如何在Linux 中使用signal 函数处理SIGINT 信号(Ctrl+C):```c#include <stdio.h>#include <signal.h>#include <unistd.h>void signal_handler(int signum) {printf("接收到信号%d\n",signum);}int main() {signal(SIGINT, signal_handler);while (1) {printf("等待信号...\n");sleep(1);}return 0;}```在这个示例中,我们设置了SIGINT 信号的处理函数为`signal_handler`。
signal函数信号是与一定的进程相联系的。
也就是说,一个进程可以决定在进程中对哪些信号进行什么样的处理。
例如,一个进程可以忽略某些信号而只处理其他一些信号;另外,一个进程还可以选择如何处理信号。
总之,这些总与特定的进程相联系的。
因此,首先要建立其信号和进程的对应关系,这就是信号的安装登记。
Linux 主要有两个函数实现信号的安装登记:signal和sigaction。
其中signal在系统调用的基础上实现,是库函数。
它只有两个参数,不支持信号传递信息,主要是用于前32个非实时信号的安装;而sigaction是较新的函数(由两个系统调用实现:sys_signal以及sys_rt_sigaction),有三个参数,支持信号传递信息,主要用来与sigqueue系统调用配合使用。
当然,sigaction同样支持非实时信号的安装,sigaction优于signal主要体现在支持信号带有参数。
对于应用程序自行处理的信号来说,信号的生命周期要经过信号的安装登记、信号集操作、信号的发送和信号的处理四个阶段。
信号的安装登记指的是在应用程序中,安装对此信号的处理方法。
信号集操作的作用是用于对指定的一个或多个信号进行信号屏蔽,此阶段对有些应用程序来说并不需要。
信号的发送指的是发送信号,可以通过硬件(如在终端上按下Ctrl-C)发送的信号和软件(如通过kill函数)发送的信号。
信号的处理指的是操作系统对接收信号进程的处理,处理方法是先检查信号集操作函数是否对此信号进行屏蔽,如果没有屏蔽,操作系统将按信号安装函数中登记注册的处理函数完成对此进程的处理。
1. signal函数(1)函数说明在signal函数中,有两个形参,分别代表需要处理的信号编号值和处理信号函数的指针。
它主要是用于前32种非实时信号的处理,不支持信号的传递信息。
但是由于使用简单,易于理解,因此在许多场合被程序员使用。
对于Unix系统来说,使用signal函数时,自定义处理信号函数执行一次后失效,对该信号的处理回到默认处理方式。
signal函数的使用signal函数是一个在C语言中使用的系统调用函数,用于处理程序运行过程中的信号。
信号是用来通知进程发生了某个事件的机制,比如用户输入了一个终止程序的指令,或者某个子进程结束了等等。
当程序收到一个信号时,可以通过使用signal函数来指定对应信号的处理方式,比如忽略该信号、执行一个特定的函数或者终止程序的执行等。
signal函数的原型如下:```cvoid (*signal(int signum, void (*handler)(int)))(int);```其中,signum表示要处理的信号的编号,handler表示信号处理函数的地址。
在使用signal函数之前,需要包含头文件<signal.h>。
下面是一个简单的例子,演示了signal函数的使用:```c#include <stdio.h>#include <signal.h>// 信号处理函数void handle_signal(int signum) {if (signum == SIGINT) {printf("Received SIGINT signal\n");// 执行自定义的处理逻辑// ...} else if (signum == SIGTERM) {printf("Received SIGTERM signal\n");// 执行自定义的处理逻辑// ...}}int main() {// 注册信号处理函数signal(SIGINT, handle_signal); // 处理SIGINT信号signal(SIGTERM, handle_signal); // 处理SIGTERM信号// 程序主逻辑while (1) {// ...}return 0;}```在上面的例子中,我们定义了一个handle_signal函数作为信号处理函数。
signal函数的使用signal系统函数调用提供了一种最简单的范例。
然而,由于C原形声明的缘故使它看起来比实际复杂。
signal函数将一个给定的函数和一个特定的信号联系。
这里是FreeBSD中的定义(和一个typedef一起):引用:typedef void (*sig_t) (int);sig_t signal(int sig, sig_t func);第一个参数是目标信号。
func参数是一个指针,指向某个处理该信号的函数。
这个处理信号函数带有一个int型参数,并应返回void。
signal函数中的func参数也可以设定为下面的一些值:引用:SIG_IGN: 如果func参数被设置为SIG_IGN,该信号将被忽略。
SIG_DFL: 如果func参数被设置为SIG_DFL,该信号会按照确定行为处理。
PS:sig信号的可能类型:#define SIGHUP 1 /* hangup */SIGHUP是Unix系统管理员很常用的一个信号。
许多后台服务进程在接受到该信号后将会重新读取它们的配置文件。
然而,该信号的实际功能是通知进程它的控制终端被断开。
缺省行为是终止进程。
#define SIGINT 2 /* interrupt */对于Unix使用者来说,SIGINT是另外一个常用的信号。
许多shell的CTRL-C组合使得这个信号被大家所熟知。
该信号的正式名字是中断信号。
缺省行为是终止进程。
#define SIGQUIT 3 /* quit */SIGQUIT信号被用于接收shell的CTRL-/组合。
另外,它还用于告知进程退出。
这是一个常用信号,用来通知应用程序从容的(译注:即在结束前执行一些退出动作)关闭。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGILL 4 /* illegal instr. (not reset when caught) */如果正在执行的进程中包含非法指令,操作系统将向该进程发送SIGILL信号。
signal函数的使用signal系统函数调用提供了一种最简单的范例。
然而,由于C原形声明的缘故使它看起来比实际复杂。
signal函数将一个给定的函数和一个特定的信号联系。
这里是FreeBSD中的定义(和一个typedef一起):引用:typedef void (*sig_t) (int);sig_t signal(int sig, sig_t func);第一个参数是目标信号。
func参数是一个指针,指向某个处理该信号的函数。
这个处理信号函数带有一个int型参数,并应返回void。
signal函数中的func参数也可以设定为下面的一些值:引用:SIG_IGN: 如果func参数被设置为SIG_IGN,该信号将被忽略。
SIG_DFL: 如果func参数被设置为SIG_DFL,该信号会按照确定行为处理。
PS:sig信号的可能类型:#define SIGHUP 1 /* hangup */SIGHUP是Unix系统管理员很常用的一个信号。
许多后台服务进程在接受到该信号后将会重新读取它们的配置文件。
然而,该信号的实际功能是通知进程它的控制终端被断开。
缺省行为是终止进程。
#define SIGINT 2 /* interrupt */对于Unix使用者来说,SIGINT是另外一个常用的信号。
许多shell的CTRL-C组合使得这个信号被大家所熟知。
该信号的正式名字是中断信号。
缺省行为是终止进程。
#define SIGQUIT 3 /* quit */SIGQUIT信号被用于接收shell的CTRL-/组合。
另外,它还用于告知进程退出。
这是一个常用信号,用来通知应用程序从容的(译注:即在结束前执行一些退出动作)关闭。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGILL 4 /* illegal instr. (not reset when caught) */如果正在执行的进程中包含非法指令,操作系统将向该进程发送SIGILL信号。
如果你的程序使用了线程,或者pointer functions,那么可能的话可以尝试捕获该信号来协助调试。
([color=Red]注意:原文这句为:“If your progr am makes use of use of threads, or pointerfunctions, try to catch this signal if possible for aid in debugging.”。
中间的两个use of use of,不知是原书排版的瑕疵还是我确实没有明白其意义;另外,偶经常听说functions pointer,对于pointer functions,google了一下,应该是fortran里面的东西,不管怎样,还真不知道,确切含义还请知道的兄弟斧正。
[/color])缺省行为是终止进程,并且创建一个核心转储。
#define SIGTRAP 5 /* trace trap (not reset when caught) */SIGTRAP这个信号是由POSIX标准定义的,用于调试目的。
当被调试进程接收到该信号时,就意味着它到达了某一个调试断点。
一旦这个信号被交付,被调试的进程就会停止,并且它的父进程将接到通知。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGABRT 6 /* abort() */SIGABRT提供了一种在异常终止(abort)一个进程的同时创建一个核心转储的方法。
然而如果该信号被捕获,并且信号处理句柄没有返回,那么进程不会终止。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGFPE 8 /* floating point exception */当进程发生一个浮点错误时,SIGFPE信号被发送给该进程。
对于那些处理复杂数学运算的程序,一般会建议你捕获该信号。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGKILL 9 /* kill (cannot be caught or ignored) */SIGKILL是这些信号中最难对付的一个。
正如你在它旁边的注释中看到的那样,这个信号不能被捕获或忽略。
一旦该信号被交付给一个进程,那么这个进程就会终止。
然而,会有一些极少数情况SIGKILL不会终止进程。
这些罕见的情形在处理一个“非中断操作”(比如磁盘I/O)的时候发生。
虽然这样的情形极少发生,然而一旦发生的话,会造成进程死锁。
唯一结束进程的办法就只有重新启动了。
缺省行为是终止进程。
#define SIGBUS 10 /* bus error */如同它的名字暗示的那样,CPU检测到数据总线上的错误时将产生SIGBUS信号。
当程序尝试去访问一个没有正确对齐的内存地址时就会产生该信号。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGSEGV 11 /* segmentation violation */SIGSEGV是另一个C/C++程序员很熟悉的信号。
当程序没有权利访问一个受保护的内存地址时,或者访问无效的虚拟内存地址(脏指针,dirty pointers,译注:由于没有和后备存储器中内容进行同步而造成。
关于野指针,可以参见/wiki/Wild_pointer 的解释。
)时,会产生这个信号。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGSYS 12 /* non-existent system call invoked */SIGSYS信号会在进程执行一个不存在的系统调用时被交付。
操作系统会交付该信号,并且进程会被终止。
缺省行为是终止进程,并且创建一个核心转储。
#define SIGPIPE 13 /* write on a pipe with no one to read it */管道的作用就像电话一样,允许进程之间的通信。
如果进程尝试对管道执行写操作,然而管道的另一边却没有回应者时,操作系统会将SIGPIPE信号交付给这个讨厌的进程(这里就是那个打算写入的进程)。
缺省行为是终止进程。
#define SIGALRM 14 /* alarm clock */在进程的计时器到期的时候,SIGALRM信号会被交付(delivered)给进程。
这些计时器由本章后面将会提及的setitimer和alarm调用设置。
缺省行为是终止进程。
#define SIGTERM 15 /* software termination signal from kill */SIGTERM信号被发送给进程,通知该进程是时候终止了,并且在终止之前做一些清理活动。
SIGTERM信号是Unix的kill命令发送的缺省信号,同时也是操作系统关闭时向进程发送的缺省信号。
缺省行为是终止进程。
#define SIGURG 16 /* urgent condition on IO channel */在进程已打开的套接字上发生某些情况时,SIGURG将被发送给该进程。
如果进程不捕获这个信号的话,那么将被丢弃。
缺省行为是丢弃这个信号。
#define SIGSTOP 17 /* sendable stop signal not from tty */本信号不能被捕获或忽略。
一旦进程接收到SIGSTOP信号,它会立即停止(stop),直到接收到另一个SIGCONT信号为止。
缺省行为是停止进程,直到接收到一个SIGCONT信号为止。
#define SIGTSTP 18 /* stop signal from tty */SIGSTP与SIGSTOP类似,它们的区别在于SIGSTP信号可以被捕获或忽略。
当shell从键盘接收到CTRL-Z的时候就会交付(deliver)这个信号给进程。
缺省行为是停止进程,直到接收到一个SIGCONT信号为止。
#define SIGCONT 19 /* continue a stopped process */SIGCONT也是一个有意思的信号。
如前所述,当进程停止的时候,这个信号用来告诉进程恢复运行。
该信号的有趣的地方在于:它不能被忽略或阻塞,但可以被捕获。
这样做很有意义:因为进程大概不愿意忽略或阻塞SIGCONT信号,否则,如果进程接收到SIGSTOP或SIGSTP的时候该怎么办?缺省行为是丢弃该信号。
#define SIGCHLD 20 /* to parent on child stop or exit */SIGCHLD是由Berkeley Unix引入的,并且比SRV 4 Unix上的实现有更好的接口。
(如果信号是一个没有追溯能力的过程(not a retroactive process),那么BSD的SIGCHID信号实现会比较好。
在system V Unix的实现中,如果进程要求捕获该信号,操作系统会检查是否存在有任何未完成的子进程(这些子进程是已经退出(exit)的子进程,并且在等待调用wait的父进程收集它们的状态)。
如果子进程退出的时候附带有一些终止信息(terminating information),那么信号处理句柄就会被调用。
所以,仅仅要求捕获这个信号会导致信号处理句柄被调用(译注:即是上面说的“信号的追溯能力”),而这是却一种相当混乱的状况。
)一旦一个进程的子进程状态发生改变,SIGCHLD信号就会被发送给该进程。
就像我在前面章节提到的,父进程虽然可以fork出子进程,但没有必要等待子进程退出。
一般来说这是不太好的,因为这样的话,一旦进程退出就可能会变成一个僵尸进程。
可是如果父进程捕获SIGCHLD信号的话,它就可以使用wait系列调用中的某一个去收集子进程状态,或者判断发生了什么事情。
当发送SIGSTOP,SIGSTP或SIGCONF信号给子进程时,SIGCHLD信号也会被发送给父进程。
缺省行为是丢弃该信号。
#define SIGTTIN 21 /* to readers pgrp upon background tty read */当一个后台进程尝试进行一个读操作时,SIGTTIN信号被发送给该进程。
进程将会阻塞直到接收到SIGCONT信号为止。
缺省行为是停止进程,直到接收到SIGCONT信号。
#define SIGTTOU 22 /* like TTIN if (tp->t_local<OSTOP) */SIGTTOU信号与SIGTTIN很相似,不同之处在于SIGTTOU信号是由于后台进程尝试对一个设置了TOSTOP属性的tty执行写操作时才会产生。
然而,如果tty没有设置这个属性,SIGTTOU就不会被发送。
缺省行为是停止进程,直到接收到SIGCONT信号。