码迷,mamicode.com
首页 > 系统相关 > 详细

linux 进程通信之 信号

时间:2015-08-03 14:33:19      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。

信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了那些系统事件。

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

信号的产生
1.用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如ctr+c产生SIGINT, ctr + \产生SIGQUI信号,ctr + z产生SIGTSTP。

2.硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给当前进程 。

3.一个进程调用int kill(pid_t pid,int sig)函数可以给另一个进程发送信号

4.可以用kill命令给某个进程发送信号,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。

5.当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号。

进程对信号的处理
1.忽略此信号
大多数信号都按照这种方式进行处理,担忧两种信号却决不能被忽略。它们是: SIGKILL 和 SIGSTOP。 这两种信号不能停止的原因是:它们向超级用户提供了一种终止或停止进程的方法。

2.执行用户希望的动作
通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理。

3.执行系统默认动作
对大多数信号的系统默认动作是终止该进程。

信号相关API

int raise(int sig);
# 向自己发送信号
# sig : 信号的signum
int kill(pid_t pid, int sig);
# 向一个指定的进程发送信号
# 参数说明
# kill 的 pid 参数有4中不同的情况
# pid > 0 : 将信号发送给进程ID为pid的进程
# pid == 0 : 将信号发送给同组的进程
# pid < 0 : 将信号发送给其进程组 ID 等于 pid绝对值的进程
# pid == -1 : 将信号发送给所有进程。
# sig:信号的signum   
# signum参考 http://blog.csdn.net/u011641885/article/details/47252003
unsigned int alarm(unsigned int seconds);
# 使用 alarm 函数可以设置一个时间值(闹钟时间),当所设置的时间到了,产生 SIGALRM 信号。
# 如果不捕捉此信号, 则默认动作是终止该进程。
# seconds : 经过指定的 seconds 秒后会产生信号 SIGALRM。

# 每个进程只能有一个闹钟时间。
# 如果在调用 alarm 时,以前已为该成绩设置过的闹钟时间,
# 而且它还没有超时,以前登记的闹钟时间则被刷新

# 如果以前登记的尚未超过的闹钟时间,
# 而这次 seconds 值是 0, 则表示取消以前的闹钟。
int pause(void);
# pause 函数使调用进程挂起直至捕捉到一个信号
# 只有执行了一个信号处理函数后,挂起才结束。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
# 注册信号,收到执行信号后做何处理
# 参数 handler 有三种情况
# SIG_IGN : 忽略该信号
# SIG_DFL : 采用系统默认方式处理信号
# 自定义的信号处理函数指针.(执行自定义操作)

示例:

#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void mysingal(int signum){
    switch(signum){
        case    SIGINT:
        case 
            break;
    }   
    return;
}

int main(int argc, char *argv[]){
    char buf[128];
    signal(SIGINT,mysingal);
    while(1){


        printf("gino@> ");

        fgets(buf,sizeof(buf),stdin);
        if(buf[0] == ‘\r‘)
            continue;


        system(buf);    

    }   


}

版权声明:本文为博主原创文章,未经博主允许不得转载。

linux 进程通信之 信号

标签:

原文地址:http://blog.csdn.net/u011641885/article/details/47255283

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!