Linux高级编程---信号截取函数signal()

合集下载

linux中的signal机制

linux中的signal机制

Linux支持的信号列表如下。很多信号是与机器的体系结构相关的,首先列出的是POSIX.1中列出的信号:
信号 值 处理动作 发出信号的原因
----------------------------------------------------------------------
break;
case 2:
printf("Get a signal -- SIGINT ");
break;
(对于SIGSYS,SIGXCPU,SIGXFSZ,以及某些机器体系结构下的SIGBUS,Linux缺省的动作是A (terminate),SUSv2 是C (terminate and dump core))。
下面是其它的一些信号
信号 值 处理动作 发出信号的原因
(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
收 到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处 理。第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信 号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。
传递给信号处理例程的整数参数是信号值,这样可以使得一个信号处理例程处理多个信号。系统调用signal返回值是指定信号signum前一次的处理例程或者错误时返回错误代码SIG_ERR。下面来看一个简单的例子:

linux signal()函数

linux signal()函数

当服务器close一个连接时,若client端接着发数据。

根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。

根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出), 所以client会退出。

若不想客户端退出可以把SIGPIPE设为SIG_IGN如: signal(SIGPIPE,SIG_IGN);这时SIGPIPE交给了系统处理。

服务器采用了fork的话,要收集垃圾进程,防止僵死进程的产生,可以这样处理:signal(SIGCHLD,SIG_IGN);交给系统init去回收。

这里子进程就不会产生僵死进程了。

signal(SIGHUP, SIG_IGN);signal信号函数,第一个参数表示需要处理的信号值(SIGHUP),第二个参数为处理函数或者是一个表示,这里,SIG_IGN表示忽略SIGHUP那个注册的信号。

SIGHUP和控制台操作有关,当控制台被关闭时系统会向拥有控制台sessionID的所有进程发送HUP信号,默认HUP信号的action是exit,如果远程登陆启动某个服务进程并在程序运行时关闭连接的话会导致服务进程退出,所以一般服务进程都会用nohup工具启动或写成一个daemon。

unix中进程组织结构为session 包含一个前台进程组及一个或多个后台进程组,一个进程组包含多个进程。

一个session可能会有一个session首进程,而一个session首进程可能会有一个控制终端。

一个进程组可能会有一个进程组首进程。

进程组首进程的进程ID与该进程组ID相等。

这儿是可能会有,在一定情况之下是没有的。

与终端交互的进程是前台进程,否则便是后台进程SIGHUP会在以下3种情况下被发送给相应的进程:1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用&符号提交的进程)2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

Linux进程间通信信号(signal)

Linux进程间通信信号(signal)

Linux进程间通信信号(signal)1. 概念: 1)信号是在软件层次上对中断机制的⼀种模拟,是⼀种异步通信⽅式 2)信号可以直接进⾏⽤户空间进程和内核进程之间的交互,内核进程也可以利⽤它来通知⽤户空间进程发⽣了哪些系统事件。

3)如果该进程当前并未处于执⾏态,则该信号就由内核保存起来,直到该进程恢复执⾏再传递给它;如果⼀个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

2.⽤户进程对信号的响应⽅式: 1)忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。

2)捕捉信号:定义信号处理函数,当信号发⽣时,执⾏相应的处理函数。

3)执⾏缺省操作:Linux对每种信号都规定了默认操作3.信号: SIGINT:ctrl+c 终⽌信号 SIGQUIT:ctrl+\ 终⽌信号 SIGTSTP:ctrl+z 暂停信号 SIGALRM:闹钟信号收到此信号后定时结束,结束进程 SIGCHLD:⼦进程状态改变,⽗进程收到信号 SIGKILL:杀死信号4.相关函数:1)int kill(pid_t pid, int sig); 功能:信号发送 参数:pid:指定进程 sig:要发送的信号 返回值:成功 0;失败 -12)int raise(int sig); 功能:进程向⾃⼰发送信号 参数:sig:信号 返回值:成功 0;失败 -13)unsigned int alarm(unsigned int seconds) 功能:在进程中设置⼀个定时器 参数:seconds:定时时间,单位为秒 返回值:如果调⽤此alarm()前,进程中已经设置了闹钟时间,则返回上⼀个闹钟时间的剩余时间,否则返回0。

注意:⼀个进程只能有⼀个闹钟时间。

如果在调⽤alarm时已设置过闹钟时间,则之前的闹钟时间被新值所代替4)int pause(void); 功能:⽤于将调⽤进程挂起直到收到信号为⽌。

linux signal代码详解 -回复

linux signal代码详解 -回复

linux signal代码详解-回复Linux Signal代码详解1. 介绍Linux系统中的信号是一种进程间通信机制,通过向目标进程发送信号来触发特定的操作或者通知。

信号常常用于进程间的同步、通知和异常处理等方面。

在Linux系统中,信号由整型数字表示,每个信号对应一个唯一的编号。

本文将一步一步分析Linux中关于信号的代码。

2. 信号的基本概念在Linux中,信号是一种软中断,它是指在运行时对一个进程的异步通知,通过发送信号可以中断目标进程的执行,或者触发目标进程相关的操作。

信号的发送可以由内核、系统管理员或者进程自身进行。

3. 信号的分类信号分为两类:标准信号和实时信号。

标准信号在系统中的编号比较小,其范围是1-31,而实时信号的编号比较大,范围是32-64。

常用的信号包括SIGKILL、SIGSTOP、SIGTERM等。

4. 信号处理机制Linux系统对信号的处理机制主要有三种:忽略、捕获和执行默认操作。

当一个进程收到信号时,可以根据需要选择不同的处理方式。

- 忽略信号:进程可以忽略某个信号,这样当该信号发送到进程时,不会有任何响应。

- 捕获信号:进程可以捕获某个信号,并自行处理。

捕获信号需要注册一个信号处理函数,该函数在接收到指定信号时被调用。

- 默认操作:每个信号都有一个默认的操作,当进程未捕获该信号时,会执行默认操作。

5. 信号处理函数的注册在Linux中,通过调用signal()函数可以注册一个信号处理函数。

该函数的原型如下:ctypedef void (*sighandler_t)(int);sighandler_t signal(int signum,sighandler_t handler);其中,signum是信号的编号,handler是一个信号处理函数的指针。

如果handler为SIG_IGN,则表示忽略该信号;如果handler为SIG_DFL,则表示使用默认操作;如果handler为一个函数指针,则表示使用自定义的信号处理函数。

Linux 信号signal处理机制

Linux 信号signal处理机制

Linux 信号signal处理机制信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。

信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。

从它的命名可以看出,它的实质和使用很象中断。

所以,信号可以说是进程控制的一部分。

一、信号的基本概念本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件。

基本概念对于理解和使用信号,对于理解信号机制都特别重要。

下面就来看看什么是信号。

1、基本概念软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。

进程之间可以互相通过系统调用kill发送软中断信号。

内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。

注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

收到信号的进程对各种信号有不同的处理方法。

处理方法可以分为三类:第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。

第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。

第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。

进程通过系统调用signal来指定进程对某个信号的处理行为。

在进程表的表项中有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。

由此可以看出,进程对不同的信号可以同时保留,但对于同一个信号,进程并不知道在处理之前来过多少个。

2、信号的类型发出信号的原因很多,这里按发出信号的原因简单分类,以了解各种信号:(1)与进程终止相关的信号。

当进程退出,或者子进程终止时,发出这类信号。

(2)与进程例外事件相关的信号。

如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。

linux sigill代码

linux sigill代码

linux sigill代码1.引言1.1 概述Linux操作系统是一种广泛使用的开源操作系统,它具有强大的性能和灵活的设计。

在Linux操作系统中,SIGILL是一个重要的代码,它代表着非法指令(illegal instruction)的意思。

SIGILL代码对于理解和分析程序的运行过程具有重要意义。

当程序执行到一个非法指令时,操作系统会发送一个SIGILL信号给程序,以通知它出现了错误。

这个信号的处理可以由程序自行定义,通常情况下,程序会终止执行并报告错误。

SIGILL代码的含义是非常灵活的。

它可以用于检测代码中的错误、优化代码执行效率,或者实现一些特定的功能。

通过对SIGILL代码的分析,我们可以发现程序中潜在的问题或者优化的空间,从而提升程序的性能和稳定性。

然而,SIGILL代码也存在一定的局限性。

首先,由于它是在程序运行过程中触发的,因此对程序的性能会有一定的影响。

其次,在某些情况下,由于代码中使用了一些特殊的指令或者不可执行的操作,导致程序产生了非法指令的情况,这可能会误判为程序存在问题。

因此,在使用SIGILL 代码时,需要谨慎处理,并结合其他方法进行综合分析。

总之,SIGILL代码在Linux操作系统中具有重要的作用。

通过对SIGILL 代码的深入理解和应用,我们可以更好地开发和优化程序,提升系统的性能和稳定性。

在本文接下来的章节中,我们将详细介绍Linux操作系统以及SIGILL代码的含义和应用。

1.2文章结构文章结构部分的内容可以包括以下内容:在本文中,将会按照以下结构展开对Linux SIGILL代码的探讨:2.正文:2.1 Linux操作系统简介:本节将从Linux操作系统的发展历程、基本特性等方面进行介绍,以帮助读者对Linux操作系统有一个基本的了解。

2.2 SIGILL代码的含义:本节将着重探讨SIGILL代码的含义及其在Linux操作系统中的作用。

将会介绍SIGILL代码的定义、产生方式以及它在操作系统中的具体应用场景。

linux高级编程-信号(2)-信号处理函数的注册方式

linux高级编程-信号(2)-信号处理函数的注册方式

linux⾼级编程-信号(2)-信号处理函数的注册⽅式信号处理函数的注册有两种⽅式,分别是简单版(signal)和⾼级版(sigaction)简单版-signal(): sighandler_t signal(int signum, sighandler_t handler); 函数描述:signal() sets the disposition of the signal signum to handler,意思就是给信号设置处理函数 参数signum:需要设置处理函数的信号 参数handler:信号处理函数地址 函数返回值:returns the previous value of the signal handler, or SIG_ERR on error,返回之前的处理⽅式,或返回错误 函数的使⽤:1/**2 * @brief handle : User-defined signal processing function3 * @param sig4*/5void handle(int sig)6 {7 std::cout << " handle signal ******* " << sig << std::endl;8 }910int main(int argc, char *argv[])11 {12// 注册⾃定义信号处理函数13if (SIG_ERR == signal(SIGINT, handle)) {14 std::cout << " Failed to registered handle ******* " << SIGINT << std::endl;15return0;16 }1718// 将信号设置为默认处理⽅式19if (SIG_ERR == signal(SIGTERM, SIG_DFL)) {20 std::cout << " Failed to registered handle ******* " << SIGTERM << std::endl;21return0;22 }2324for (;;) {sleep(1);}25 } 运⾏结果查看: 通过运⾏结果查看,可以看出当按下 ctrl + c 的时候都会执⾏⾃定义信号处理函数 ⾼级版的使⽤-sigaction():  int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact); 函数描述: 参数signum:需要处理的信号 参数act和参数oldact:If act is non-NULL, the new action for signal signum is installed from act. If oldact is non-NULL, the previous action is saved in oldact struct sigaction { void (*sa_handler)(int); //信号处理程序,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认动作 void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序,能够接受额外数据和sigqueue配合使⽤ sigset_t sa_mask;//阻塞关键字的信号集,可以再调⽤捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。

Signal ()函数详细介绍 Linux函数

Signal ()函数详细介绍 Linux函数

Signal ()函数详细介绍Linux函数signal()函数理解在这个头文件中。

signal(参数1,参数2);参数1:我们要进行处理的信号。

系统的信号我们可以再终端键入kill -l查看(共64个)。

其实这些信号时系统定义的宏。

参数2:我们处理的方式(是系统默认还是忽略还是捕获)。

一般有3中方式进行操作。

(1)eg: signal(SIGINT ,SIG_ING );//SIG_ING 代表忽略SIGINT信号,SIGINT信号代表由InterruptKey产生,通常是CTRL+C 或者是DELETE 。

发送给所有ForeGround Group的进程。

下面我们写个死循环:这时我们保存执行。

按下CTRL _C程序没有反应。

这就对了如果我们想结束该程序可以按下CTRL +\来结束其实当我们按下CTRL +\组合键时,是产生了SIGQUIT信号(2)eg: signal(SIGINT ,SIG_DFL );//SIGINT信号代表由InterruptKey产生,通常是CTRL +C或者是DELETE。

发送给所有ForeGroundGroup的进程。

SIG_DFL代表执行系统默认操作,其实对于大多数信号的系统默认动作时终止该进程。

这与不写此处理函数是一样的。

我们将上面的程序改成这时就可以按下CTRL +C 来终止该进程了。

把signal(SIGINT,SIG_DFL);这句去掉,效果是一样的。

(3)void ( *signal( int sig, void (* handler)( int )))( int );int (*p)();这是一个函数指针, p所指向的函数是一个不带任何参数, 并且返回值为int的一个函数.int (*fun())();这个式子与上面式子的区别在于用fun()代替了p,而fun()是一个函数,所以说就可以看成是fun()这个函数执行之后,它的返回值是一个函数指针,这个函数指针(其实就是上面的p)所指向的函数是一个不带任何参数,并且返回值为int的一个函数.void (*signal(int signo, void (*handler)(int)))(int);就可以看成是signal()函数(它自己是带两个参数,一个为整型,一个为函数指针的函数),而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带一个整型参数,并且返回值为void的一个函数.在写信号处理函数时对于信号处理的函数也是voidsig_fun(int signo);这种类型,恰好与上面signal()函数所返回的函数指针所指向的函数是一样的.void ( *signal() )( int ); signal是一个函数, 它返回一个函数指针,后者所指向的函数接受一个整型参数且没有返回值, 仔细看, 是不是siganal( int signo, void (*handler)(int) )的第2个参数了,对了,其实他所返回的就是signal的第2个信号处理函数,指向信号处理函数,就可以执行函数了(signal内部时, signal把信号做为参数传递给handler信号处理函数,接着signal函数返回指针,并且又指向信号处理函数, 就开始执行它)那么,signal函数的参数又是如何呢?signal函数接受两个参数:一个整型的信号编号,以及一个指向用户定义的信号处理函数的指针。

signal函数的功能和作用

signal函数的功能和作用

signal函数的功能和作用信号是操作系统中用于通知进程发生了某些事件的机制,例如进程收到了一个新的网络连接、进程终止、进程接收到了一个外部信号等等。

信号是异步的,即它可以在任何时候发生,进程需要有一种机制来响应这些信号。

signal函数就是用来处理信号的函数。

signal函数用于捕捉当前进程收到的特定信号,并执行指定的信号处理函数。

signal 函数的原型如下:#include <signal.h>void (*signal(int signum, void (*handler)(int)))(int);该函数接收两个参数:signum:是要处理的信号类型,例如SIGINT代表中断信号,SIGABRT代表异常终止信号等等。

handler:是指定的信号处理函数,当进程收到该信号时会执行该函数。

handler的类型为void (*handler)(int),它接收一个int类型的参数作为信号编号。

signal函数主要用于以下三个方面:1. 捕捉信号如果进程没有安装信号处理函数,那么它会使用默认的处理方式来处理信号,例如忽略信号、终止进程等等。

在signal函数被调用之后,在当前进程中,指定的信号类型的处理方式就会被改变为执行指定的信号处理函数。

2. 处理信号当进程接收到捕捉的信号时,指定的信号处理函数就会被执行。

在这个函数中,我们可以做一些特定的处理,例如记录日志、关闭文件、释放资源等等。

在信号处理函数执行完毕之后,进程会回到原来的位置继续执行。

3. 回归默认信号处理方式如果需要,我们也可以使用signal函数将信号处理方式恢复为默认值。

这通常在我们不需要通过信号来处理特定事件时使用,或者在我们需要使用默认的方式来处理信号时使用。

综上所述,signal函数是一个非常重要的函数,它可以帮助我们处理进程接收到的信号,并执行指定的信号处理函数。

它的作用是多方面的,可以让我们在进程发生意外情况时,更好地处理异常信息,提高进程的稳定性。

linux signal方法

linux signal方法

linux signal方法(原创版3篇)《linux signal方法》篇1在Linux 中,signal 方法是一种用于设置信号处理函数的函数,用于在接收到特定信号时执行特定的操作。

signal 方法的原型为:```cvoid (signal(int signum, void (*handler)(int));```其中,signum 表示要设置信号处理函数的信号编号,handler 表示信号处理函数的函数指针。

在Linux 中,信号是一种异步事件,用于向进程发送通知或控制信息。

当进程接收到信号时,它会立即中断当前正在执行的操作,并跳转到信号处理函数中去执行。

如果进程没有设置信号处理函数,则系统会默认执行一些操作,例如打印出信号的信息并终止进程。

使用signal 方法可以设置信号处理函数,以处理接收到的信号。

信号处理函数可以是一个程序员定义的函数,也可以是一个系统提供的函数。

在信号处理函数中,可以通过信号处理函数的参数来获取信号的相关信息,例如信号编号和信号代码等。

需要注意的是,在信号处理函数中不能使用阻塞性操作,例如等待I/O 操作完成等,否则会导致信号处理函数无法及时返回,从而影响进程的正常执行。

《linux signal方法》篇2在Linux 中,signal 方法是一种用于设置信号处理函数的函数。

当进程接收到指定的信号时,就会执行信号处理函数。

signal 方法的原型为:```cvoid (signal(int signum, void (handler)(int)))(int);```其中,signum 表示要设置信号处理函数的信号编号,handler 表示信号处理函数的函数指针,返回值为整型。

在使用signal 方法时,需要先调用sigaction 函数设置信号处理函数,然后将信号处理函数的地址传递给signal 方法。

sigaction 函数的原型为:```cint sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);```其中,signum 表示要设置信号处理函数的信号编号,act 表示新的信号处理函数,oldact 表示旧的信号处理函数。

signal函数的参数

signal函数的参数

signal函数的参数一、概述Signal函数是编程中常用的一种函数,用于处理程序中的异常和错误。

它接受不同的参数,以决定如何处理信号。

这些参数包括信号的编号、处理方式、附加数据等。

理解信号函数的参数对于正确使用Signal函数非常重要。

二、信号编号信号编号是Signal函数的最基本参数,它表示要处理的信号类型。

不同的信号类型代表了不同的异常或错误情况,如非法输入、内存不足、文件不存在等。

在Unix/Linux系统中,常用的信号编号包括SIGINT(中断信号)、SIGTERM(终止信号)等。

三、处理方式处理方式决定了当信号发生时,程序如何响应。

常见的处理方式有:1.忽略:忽略信号,程序不会做出任何反应。

2.捕获:在程序中定义一个信号处理程序来处理信号。

当信号发生时,执行相应的处理程序。

3.重新调度:重新调度信号的处理程序,允许其他进程在信号发生时被调度。

4.阻塞:将信号阻塞,即程序不会响应该信号,直到该信号被解除阻塞。

四、附加数据Signal函数还可以接受附加数据参数,用于传递额外的信息或状态。

这些数据可以在信号处理程序中使用,以执行更复杂的操作或决策。

附加数据的类型和数量取决于具体的应用场景和需求。

五、使用示例下面是一个使用Signal函数处理不同信号的示例代码:```c#include<stdio.h>#include<signal.h>#include<unistd.h>voidsignal_handler(intsignal_num,siginfo_t*si,void*uc){ switch(signal_num){caseSIGINT:printf("ReceivedSIGINT,shuttingdown...\n");exit(0);default:printf("Unexpectedsignal:%d\n",signal_num);}}intmain(){//注册SIGINT信号处理程序signal(SIGINT,signal_handler);//等待一段时间后触发SIGINT信号sleep(5);printf("Programexiting...\n");return0;}```上述代码中,我们使用signal函数注册了一个SIGINT信号的处理程序。

linux sigill代码 -回复

linux sigill代码 -回复

linux sigill代码-回复“sigill”是Linux系统中的一个错误信号(signal),它通常表示“无效指令(illegal instruction)”。

当程序遇到无效的指令时,操作系统会向程序发送这个信号,以提醒开发者修复程序中的错误。

在这篇文章中,我将详细介绍sigill的含义、发生的原因以及如何调试和处理这个错误。

首先,我们需要了解什么是信号(signal)。

在计算机科学中,信号是一种在操作系统中用于通知进程发生了某种事件的机制。

操作系统可以在进程之间、操作系统内核和进程之间或者硬件和操作系统之间触发这些事件。

一般来说,信号用于通知程序发生了某种错误或者特殊事件,需要采取相应的处理措施。

在Linux系统中,“sigill”信号是一个非常特殊的信号,它表示程序执行的是一个无效的指令。

通常情况下,这种情况发生时是因为程序引用了一个不存在或不被支持的指令,或者在执行时访问了不允许访问的内存区域。

这可能是由于程序本身错误、编译错误或者操作系统错误引起的。

那么,当我们的程序遇到“sigill”信号时,我们该如何处理呢?以下是一些常见的处理方法和调试技巧:1. 阅读错误信息:当程序遇到“sigill”信号时,操作系统通常会打印一条错误消息,提示你程序中引发错误的位置和原因。

仔细阅读错误信息可以帮助你更好地理解问题所在,并且有助于问题的诊断和调试。

2. 检查程序的指令集:当程序遇到“sigill”信号时,首先要确认程序运行的是正确的指令集。

在Linux系统中,可以使用命令“file <程序路径>”来查看程序编译时使用的指令集。

如果指令集不匹配,程序很可能会遇到“sigill”信号。

3. 检查编译选项:如果程序运行的是正确的指令集,但仍然遇到“sigill”信号,那么可能是编译过程中出现了问题。

请检查编译选项是否正确设置,特别是和指令集相关的选项。

可能需要调整编译选项,以确保生成的可执行文件与目标系统兼容。

Linux信号详解一(signal函数)

Linux信号详解一(signal函数)

Linux信号详解⼀(signal函数)信号列表SIGABRT 进程停⽌运⾏6SIGALRM 警告钟SIGFPE 算述运算例外SIGHUP 系统挂断SIGILL ⾮法指令SIGINT 终端中断2SIGKILL 停⽌进程(此信号不能被忽略或捕获)SIGPIPE 向没有读的管道写⼊数据SIGSEGV ⽆效内存段访问SIGQOUT 终端退出3SIGTERM 终⽌SIGUSR1 ⽤户定义信号1SIGUSR2 ⽤户定义信号2SIGCHLD ⼦进程已经停⽌或退出SIGCONT 如果被停⽌则继续执⾏SIGSTOP 停⽌执⾏SIGTSTP 终端停⽌信号SIGTOUT 后台进程请求进⾏写操作SIGTTIN 后台进程请求进⾏读操作typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);signal函数作⽤1:站在应⽤程序的⾓度,注册⼀个信号处理函数作⽤2:忽略信号,设置信号默认处理信号的安装和回复参数--signal是⼀个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调⽤的函数有handler给出--handler这个函数必须有⼀个int类型的参数(即接收到的信号代码),它本⾝的类型是void--handler也可以是下⾯两个特殊值:① SIG_IGN 屏蔽该信号② SIG_DFL 恢复默认⾏为//忽略,屏蔽信号#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <signal.h>int main(int arg, char *args[]){pid_t pid=fork();if(pid==-1){printf("fork() failed! error message:%s\n",strerror(errno));return -1;}//注册信号,屏蔽SIGCHLD信号,⼦进程退出,将不会给⽗进程发送信号,因此也不会出现僵⼫进程signal(SIGCHLD,SIG_IGN);if(pid>0){printf("father is runing !\n");sleep(10);}if(pid==0){printf("i am child!\n");exit(0);}printf("game over!\n");return0;}//恢复信号#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <signal.h>void catch_signal(int sign){switch (sign){case SIGINT:printf("ctrl + C 被执⾏了!\n");//exit(0);break;}}int main(int arg, char *args[]){//注册终端中断信号signal(SIGINT, catch_signal);char tempc = 0;while ((tempc = getchar()) != 'a'){printf("tempc=%d\n", tempc);//sleep()}//恢复信号signal(SIGINT, SIG_DFL);while (1){pause();}printf("game over!\n");return0;}//signal()函数的返回值#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <signal.h>void catch_signal(int sign){switch (sign){case SIGINT:printf("ctrl + C 被执⾏了!\n");//exit(0);break;}}int main(int arg, char *args[]){/** signal()函数的返回值是signal()函数上⼀次的⾏为* */typedef void (*sighandler_t)(int);//因为第⼀次注册信号SIGINT,所以上⼀次的⾏为就是默认⾏为 sighandler_t old=signal(SIGINT, catch_signal);if(old==SIG_ERR){//注册信号失败perror("signal error");}/*正规写法*/if(signal(SIGQUIT,catch_signal)==SIG_ERR){//注册新号失败perror("signal error");}char tempc = 0;while ((tempc = getchar()) != 'a'){printf("tempc=%d\n", tempc);//sleep()}//把默认⾏为重新注册,不就是恢复默认信号了signal(SIGINT, old);while (1){pause();}printf("game over!\n");return0;}。

signal函数

signal函数

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函数

实验四进程间通信UNIX/LINUX系统的进程间通信机构(IPC)允许在任意进程间大批量地交换数据。

本实验的目的是了解和熟悉LINUX支持的信号量机制、管道机制、消息通信机制及共享存储区机制。

(一)信号量机制实验【实验目的】1.了解什么是信号。

2.熟悉LINUX系统中进程之间软中断通信的基本原理。

【实验内容】1.编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到父进程发来的信号后,分别输出下列信息后终止:Child process 1 is killed by parent!Child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止:Parent process is killed!<参考程序># include<stdio.h># include<signal.h># include<unistd.h>int wait_mark;void waiting(),stop();void main(){ int p1, p2;signal(SIGINT,stop);while((p1=fork())==-1);if(p1>0) /*在父进程中*/{①while((p2=fork())= =-1);If(p2>0) /*在父进程中*/{ ②wait_mark=1;waiting(0);kill(p1,10);kill(p2,12);wait( );wait( );printf(“parent process is killed!\n”);exit(0);}else /*在子进程2中*/{wait_mark=1;signal(12,stop);waiting();lockf(1,1,0);printf(“child process 2 is killed by parent!\n”);lockf(1,0,0);exit(0);}}else /*在子进程1中*/{wait_mark=1;signal(10,stop);waiting();lockf(1,1,0);printf(“child process 1 is killed by parent!\n”);lockf(1,0,0);exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}实验要求:⑴运行程序并分析结果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

信号处理有两种方法,一种是利用signal()函数,另外一种是使用信号集函数。

这里主要介绍signal()函数的使用。

signal()函数用于获取系统产生的各种信号,并对此信号调用用户自己定义的处理函数,函数原型如下所示:#include <signal.h>
typedef void sign(int);
sign *signal(int,handler *) ;
signal()函数有两个参数,第一个参数指定信号的值,第二个参数是一个函数指针,用于指定针对信号的处理函数的函数地址。

将前面的alarm.c代码中引入信号处理函数signal(),signal.c的代码如下所示:
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void signal_handler()
{
printf("定时时间结束\n");
return;
}
main()
{
int number;
signal(SIGALRM,signal_handler);
alarm(5);
for(number=1;number<=10;number++)
{
printf("时间过去%d秒钟!\n",number);
sleep(1);
}
}
该代码依然设置一个5秒钟的定时,与之前的处理方法不同,此处加入了捕获SIGALRM信号的处理函数,当定时5秒到来时,signal()函数捕获了SIGALRM 信号并交由signal_handler()函数处理,该信号处理函数打印定时时间结束的提示信息后退出。

由于alarm()函数本身不是阻塞函数,其后面的for()循环依然继续运行,运行代表的含义为一个1~10的时间计时。

只是在计时5秒钟后加入了一个“定时时间结束”的打印信息。

编译signal.c,生成signal可执行文件后并运行:
# gcc –o signal signal.c
# ./signal
代码运行效果如下图所示:。

相关文档
最新文档