进程间通信—信号

来源:互联网 发布:1-10抽奖概率算法 编辑:程序博客网 时间:2024/06/05 08:27

信号念:

信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。进程在接收到这个信号以后,可以设置响应的处理动作:忽略或者调用函数进行处理。

在linux下命令行$kill-l

可以查看linux下的所有信号:一共64个信号,从1开始编号,其中也存在0号信号,但是0号信号是用来测试某个进程是否存在。其中1-32号信号是经典信号,不支持排队的(就是无论产生了多少次该信号都只当成一次处理),后面的32个信号是实时信号常用来驱动编程,并且是支持排队的(产生多少次就记录多少次,一次一次处理)。

信号的产生来源:

1终端的特殊按键:

       Ctrl +c   SIGINT

       Ctrl +z   SIGTSTP

       Ctrl +\   SIGQUIT

2、硬件产生:

段错误:非法的操作内存,然后操作系统发送11号信号提示段错误

浮点数例外:除0操作提示浮点数例外,CPU不能除0操作,否则发送8号信号终止进程。

3、Kill函数或者kill命令:(kill  -信号编号  进程号

向某一个进程或者进程组发送信号,但是这个时候只能向自己的进程发送信号,不能发送给其他进程。

root用户可以向所有进程发信号

4、某种软件引发的信号,每个进程有且仅有一个定时器

int raise(int sig ); 

函数向自己发送sig号信号

abort()调用进程自己向自己发送6号信号(sigabort)终止自己

unsigned int alarm(unsign int second ) 

函数的精度是秒,定时一个具体的second 秒数,到时之后给发送自己一个sigarm信号终止自己。

进程处理信号的3种行为

1、默认处理,分以下五种方式

term  终止进程

Ign   忽略(层级不同)

stop  暂停

core  先终止进程然后生成core文件,死后验尸用于GDB调试

cont  继续运行

2、忽略

3、捕捉:用户自定义捕捉函数处理

信号集处理函数 sigset_t为信号集合(128字节

                     信号集在进程控制块中(PCB)有专门用来处理信号的集合。


#include <signal.h>

Int sigempty(sigset_t *set);  //将信号集都清0

Int sigfillset(sigset_t *set);  //将信号集都置1

Int sigaddset(sigset_t *set,int signo);//将信号集的某一位置1

Int sigdlset(sigset_t*set,int signo);//将信号集的某一位置0

Int sigismember(const sigset_t *set, int signo);//判断某一位信号是否是1

设置好信号集后将该信号集合注册到当前进程中的阻塞信号集中。

Int  sigprocmask( int how, const*sigset_t *set ,sigset_t *oset);

第一个set是新传入进来的参数

第二个Oset是旧的信号屏蔽字是传出参数,用于备份,不需要时传NULL

How 有三种选择操作:

SIG_BLOCK    set的信号屏蔽字中添加到当前信号屏蔽字

SIG_UNBLOCK  set信号屏蔽字中解除阻塞的信号

SIG_SETMASK   将set完全替换当前的信号屏蔽字

int sigpending (sigset_t *set)//获取当前进程的未决信号集

sigkill和sigstop信号 不可以被阻塞,可以被这两个信号强制杀死

信号的捕捉函数的设定

Int sigaction(int signum , Cosnt struct sigaction  *act ,struct sigaction *oldact);

第一个是为哪个信号设置捕捉函数

第二个是为该信号设置的动作处理函数

第三个是原有的默认处理动作,不关心时传NULL

Struct sigaction {

void (*sa_handler)(int );

void (*sa_sigaction)(int ,siginfo_t*, void *);

sigset_t  sa_mask; //一个临时的信号屏蔽字。某个信号产生时调用捕捉函数时(假如时间比较长),内核会阻塞该信号,防止在调用捕捉函数的时间内,该信号又到来,使得程序出错。调用完内核会自动解除阻塞。也可以根据sa_mask信号集增加其他的阻塞信号。

Int sa_flag;  //该标志说明调用第一个(flag==0时默认)还是第二个函数指针,只能二选一。

Void (*sa_restorer)(void ); //废弃保留

}

时间片的轮转靠的是CPU的定时中断,内核去剥夺程序使用CPU的权利

系统调用都要往内核去调用函数,CPU切换到内核状态。

信号产生以后并不是第一时间进行响应,中断产生,CPU才首先处理信号

操作系统没有明确定义的信号,SIGUSR1和SIGUSR2默认是终止进程,用户可以自己定义这两个信号的行为

不能随便更改系统的信号,如终端按键产生的信号

C标准库的信号处理函数

typedef   void (*sighandler_t)(int )     

sigheadler  signal(intsignum,sighandler_t handler); //在windows上和linux都可以使用。之前的只能在Linux

system(const char*conmmand);    //集fork() exec()wait()函数一体;

优点是接口简单,然后使用方便,跨平台

缺点的话:不能更改信号屏蔽字。功能简单



原创粉丝点击