欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

进程间的通信——信号

程序员文章站 2022-07-12 10:31:04
...

信号是linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应的采取一些行动。可作为进程间传递消息的一种方式,信号可以被生成、捕获、响应或忽略。信号在signal.h中定义,信号的名称都以SIG开头如:SIGALRM 超时警告;SIGINT:终端中断。 如果进程接收到这些信号中的一个,但是事先没有安排捕获它,进程将会立刻终止。

1.kill发送信号

进程通过调用kill函数向其他进程发送一个信号,成功时返回0,失败时返回-1
其定义为int kill(pid_t pid, int sig),kill函数把sig给定的信号发送给参数pid给出的进程号所指定的进程。

2.signal函数

该函数的定义为void (*signal(int sig, void (*func)(int)))(int),带有sig和func两个参数,准备捕获的信号为sig参数,接收到指定的信号后将要调用的函数由参数func指定,信号处理函数必须有一个int类型的参数(即接受到的信号代码)并且返回类型为void.

3.程序源码

以模拟闹钟的形式,通过一个进程向另一个进程发送SIGALRM信号来表现进程间的通信。

vi alarm.c
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

static int alarm_fired = 0;

/*该函数用来模拟闹钟*/
void ding(int sig)
{
    alarm_fired =1;
}

/*main函数中告诉子进程在等待5秒后发送SIGALRM信号给它的父进程*/
int main()
{
    pid_t pid;
    printf("alarm start\n");
    pid = fork();  /*创建子进程*/
    switch (pid)
    {
    case -1:
        perror("fork failed");
        exit(1);
    
    case 0:
        sleep(5);  /*子进程休眠5秒*/
        kill(getppid(), SIGALRM);  /*子进程在5秒后将SIGALRM信号传递给父进程*/
        exit(0);
}

/*父进程通过一个signal调用捕获SIGALRM信号的工作,等待该信号的到来*/
    printf("waitting for alarm to go on\n");
    (void) signal(SIGALRM, ding);
    pause();
    if (alarm_fired)
        printf("ding!\n");
    printf("done\n");
    exit(0);
}

编译运行

cc -o alarm alarm.c -g
./alarm

进程间的通信——信号
参考:Linux程序设计第四版
进程间的通信——信号