进程间通信--信号

信号

信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。

信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。

信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。

信号来源 信号事件的发生有两个来源: 硬件来源(比如我们按下了键盘或者其它硬件故障);

软件来源,最常用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操作。

进程可以通过三种方式来响应一个信号: (1)忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP;

(2)捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数;

(3)执行缺省操作,Linux对每种信号都规定了默认操作,详细情况请参考资料。 注意,进程对实时信号的缺省反应是进程终止。

Linux究竟采用上述三种方式的哪一个来响应信号,取决于传递给相应API函数的参数。

发送信号的主要函数有:

kill()

#include <sys/types.h>

#include <signal.h>

int kill(pid_t pid,int signo)

参数pid的值为信号的接收进程

Kill()最常用于pid>0时的信号发送,调用成功返回 0; 否则,返回 -1。

注:对于pid<0时的情况,对于哪些进程将接受信号,各种版本说法不一,其实很简单,参阅内核源码kernel/signal.c即可

raise()

#include <signal.h>

int raise(int signo) 向进程本身发送信号,参数为即将发送的信号值。

调用成功返回 0;否则,返回 -1。

sigqueue()

#include <sys/types.h>

#include <signal.h>

int sigqueue(pid_t pid, int sig, const union sigval val)

调用成功返回 0;否则,返回 -1。 sigqueue()是比较新的发送信号系统调用,

主要是针对实时信号提出的(当然也支持前32种),支持信号带有参数,与函数sigaction()配合使用。

sigqueue的第一个参数是指定接收信号的进程ID,第二个参数确定即将发送的信号,

第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

typedef union sigval

{

int sival_int;

void *sival_ptr;

}sigval_t;

sigqueue()比kill()传递了更多的附加信息, sigqueue() 只能向一个进程发送信号,而不能发送信号给一个进程组。

如果signo=0,将会执行错误检查,但实际上不发送任何信号,0值信号可用于检查pid的有效性以及当前进程是否有权限向目标进程发送信号。 在调用sigqueue时,sigval_t指定的信息会拷贝到3参数信号处理函数(3参数信号处理函数指的是信号处理函数由sigaction安装,并设定了sa_sigaction指针)

alarm()

#include <unistd.h>

unsigned int alarm(unsigned int seconds)

专门为SIGALRM信号而设,在指定的时间seconds秒后,将向进程本身发送SIGALRM信号,又称为闹钟时间。

进程调用alarm后,任何以前的alarm()调用都将无效。如果参数seconds为零,那么进程内将不再包含任何闹钟时间。

返回值,如果调用alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。

setitimer()

#include <sys/time.h>

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

setitimer()比alarm功能强大,支持3种类型的定时器:

ITIMER_REAL: 设定绝对时间;经过指定的时间后,内核将发送SIGALRM信号给本进程;

ITIMER_VIRTUAL 设定程序执行时间;经过指定的时间后,内核将发送SIGVTALRM信号给本进程;

ITIMER_PROF 设定进程执行以及内核因本进程而消耗的时间和,经过指定的时间后,内核将发送ITIMER_VIRTUAL信号给本进程;

Setitimer()第一个参数which指定定时器类型(上面三种之一);

第二个参数是结构itimerval的一个实例,结构itimerval形式见附录1。

第三个参数可不做处理。

Setitimer()调用成功返回0,否则返回-1。

abort()

#include <stdlib.h>

void abort(void);

向进程发送SIGABORT信号,默认情况下进程会异常退出,当然可定义自己的信号处理函数。

即使SIGABORT被进程设置为阻塞信号,调用abort()后,SIGABORT仍然能被进程接收。该函数无返回值。

信号的安装

如果进程要处理某一信号,那么就要在进程中安装该信号。

安装信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系, 即进程将要处理哪个信号;

该信号被传递给进程时,将执行何种操作。

linux主要有两个函数实现信号的安装: signal()、sigaction()。 signal()在可靠信号系统调用的基础上实现, 是库函数。

它只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;

sigaction()是较新的函数(由两个系统调用实现:sys_signal以及sys_rt_sigaction),有三个参数,支持信号传递信息,主要用来与 sigqueue() 系统调用配合使用,当然,sigaction()同样支持非实时信号的安装。sigaction()优于signal()主要体现在支持信号带有参数。

时间: 2024-10-01 15:51:57

进程间通信--信号的相关文章

Linux进程间通信——信号

一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中的进程捕获到这个信号然后作出一定的操作并最终被终止. 信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动.通常信号是由一个错误产生的.但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程.一个信号的产生叫生成,接收到一个信号

进程间通信——信号

进程间通信--信号 宗旨:技术的学习是有限的,分享的精神的无限的. 一.信号和中断 1.信号基本概念 (1)发送信号:产生信号,有多种发送信号的方式[一个进程到另一个进程,内核向用户,进程向自己] (2)安装信号:设置信号到来时不再执行默认操作,而是执行自定义的代码. (3)递送信号:一个信号被操作系统发送到目标进程引起某段处理程序的执行. (4)捕获信号:被递送的信号在目标进程引起某段处理程序的执行. (5)屏蔽信号:进程告诉操作系统暂时不接受某些信号. (6)忽略信号:进程被递送到目标进程,

进程间通信--信号(进程间通信唯一的异步方式)

一.信号的介绍 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式. 信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了那些系统事件. 如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递个它:如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞取消时才被传递给进程. 二.linux操作系统支持的信号 A. kill  -l B.常用信号的含义 三.信号的产生 A.用户在终端按下某些键时,终端驱动程序会发送

详解linux进程间通信-信号

前言:之前说看<C++ Primer >暂时搁浅一下,迷上公司大神写的代码,想要明白,主要是socket.进程间通信! 知道进程间通信:信号.信号量.管道.消息队列.共享内存(共享存储),也能写些简单代码进行通信,但不知道应用在哪?感觉很多小伙伴跟我有类似经历吧? 一.应用实例: 要去linux设备上去添加.改密用户:本地去linux设备添加用户,用socket实现,其实大神改的ssh源码来实现的,这不是我要讲的重点,而我要讲的是准备过程,去登陆linux设备,要准备好:管理员.密码等. 简略

Linux进程间通信 -- 信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我们需要处理的信号,我们不需要处理哪些信号等问题呢?信号集函数就是帮助我们解决这些问题的. 有关Linux进程间使用信号通信的更多内容,可以参阅我的另一篇文章,Linux进程间通信 -- 信号量函数 signal().sigaction() 下面是信号函数集: 1.int sigemptyset(si

Linux进程间通信—信号

三.信号(Signal) 信号是Unix系统中使用的最古老的进程间通信的方法之一.操作系统通过信号来通知某一进程发生了某一种预定好的事件:接收到信号的进程可以选择不同的方式处理该信号,一是可以采用默认处理机制—进程中断或退出,一是忽略该信号,还有就是自定义该信号的处理函数,执行相应的动作. 内核为进程生产信号,来响应不同的事件,这些事件就是信号源.信号源可以是:异常,其他进程,终端的中断(Ctrl-C,Ctrl+\等),作业的控制(前台,后台进程的管理等),分配额问题(cpu超时或文件过大等),

Linux进程间通信 -- 信号量函数 signal()、sigaction()

一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中的进程捕获到这个信号然后作出一定的操作并最终被终止. 信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动.通常信号是由一个错误产生的.但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程.一个信号的产生叫生成,接收到一个信号

Linux信号(signal) 机制分析

[摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执行及注销等.最后介绍了应用层的相关处理,主要包括信号处理函数的安装.信号的发送.屏蔽阻塞等,最后给了几个简单的应用实例. [关键字]软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t 1       信

Linux进程间通信 -- 信号量 semget()、semop()、semctl()

这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信 -- 信号.下面就进入信号量的讲解. 一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同