进程间通信之信号通信(一)

信号概述

    信号是软件中断。信号机制是Unix系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号

   很多条件可以产生一个信号

    1、当用户按某些中断键是,产生信号。在终端按DELETE键通常产生中断信号

    2、硬件异常产生信号:除数为0,无效的存储访问等等

    3、进程用kill(l)函数可将信号发送给另一个进程或进程组

    4、用户可用kill(2)命令将信号发送给其他进程

    5、当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号

信号源 

    内核为进程产生信号。来响应不同的事件,这些事件就是信号源,主要的信号源有:

    1、异常:进程运行过程中出现异常

    2、其他进程:一个进程可以向另一个或一组进程发送信号

    3、终端中断:ctrl+C 等

    4、作业控制:前台,后台进程的管理

    5、分配额:CPU超时或文件大小突破限制

    6、通知:通知进程某事件发生

    7、报警:计时器到期

Linux中的信号

    kill-l命令显示系统信号

    1-31不可靠信号  34-64为可靠信号

    可靠信号支持多次注册,排队处理

   

信号的处理过程

    由内核进程产生信号------->用户进程完成信号注册,信号注销-------->信号处理

信号出现时按照下列三种方式中的一种进行操作

    1、忽略此信号 SIGKILL和SIGSTOP不能忽略

    2、捕捉信号 调用一个用户函数

    3、执行系统默认动作   每一个信号都有一个缺省动作,他是进程没有给这个信号指定处理程序时,内核对信号的处理。有5种缺省动作:

        1)异常中止(abort):在进程的当前目录下,把进程的地址空间内容,寄存器内容保存到一个叫做core的文件中,而后终止进程

        2)退出(exit):不产生core文件,直接终止进程

        3)忽略(ignore):忽略该信号

        4)停止(stop):挂起该进程

        5)继续(continue):如果进程被挂起,则恢复进程的运行。否则,忽略信号。

kill()和raise()

    kill()不仅可以终止进程,也可以向进程发送其他信号。

    raise()函数运行向进程本身发送信号

    头文件:#include<sys/types.h>  #include<signal.h>

    函数定义:int kill(pid_t pid,int signo);

                     int raise(int signo);

    函数返回值:均为成功返回0,出错返回-1;

//kill()  raise()
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/wait.h>

int main()
{
    pid_t pid;
    int i,ret;
    if((pid=fork())<0)
    {
        printf("fork error\n");
        exit(1);
    }
    if(pid == 0)
    {
        printf("I am child %d\n",getpid());
        for(i=0;i<10;i++)
        {
            sleep(1);
            printf("child printf %d\n",i);
            if(i == 3)
            {
                printf("child stop \n");
                raise(SIGSTOP);//子进程发信号给自己,终止进程
            }
            if(i == 4 )
            {
                printf("child is killed");
                raise(SIGINT);//子进程发信号给自己,退出进程
            }
            printf("#####%d#######\n",i);
        }
        exit(0);
    }
    else if(pid != 0)
    {
        printf("child pid is %d",pid);
        printf("parent pid is %d",getpid());
        sleep(5);
        if((waitpid(pid,NULL,WNOHANG))==0)
        {
            if((ret=kill(pid,SIGCONT))==0)//父进程发信号给子进程,让子进程继续执行
                printf("cont %d\n",pid);
            else{
                perror("cont");
            }
        }
        printf("++++\n");
    }
}





程序执行结果

  

猜你喜欢

转载自blog.csdn.net/error0_dameng/article/details/81701264