Linux 下进程间通信机制(三) 信号Signal

来源:互联网 发布:小米快传软件 编辑:程序博客网 时间:2024/05/17 01:37

信号的响应函数
void(*signal(int signum, void(*handler)(int)))(int);


解释:
signum:指定的信号(系统支持的)
handler:可能的取值有三种 SIG_IGN(忽略该信号)   SIG_DFL(系统默认操作) 自定义的处理函数指针
成功: 返回上一次设置的函数指针

失败:-1


demo1:

#include<stdio.h>#include<unistd.h>#include<signal.h>typedef void(*pFunc)(int);void myhandler1(int signo){    printf("myhander1 signo:%d\n", signo);}void myhandler2(int signo){    printf("myhander2 signo:%d\n", signo);}int main(){    pFunc hander1, hander2;    hander1 = signal(14, myhandler2);//第一次设置响应函数    hander2 = signal(14, myhandler1); //设置信号响应函数,返回上一次设置的响应函数指针,但不会返回默认。    alarm(5);//SIGALARM已经被设置响应函数 打印myhander1 signo:14    pause();    //hander1(100);//这里并没有返回默认的响应函数,会出现段错误    hander2(100); //打印myhander2 signo:100    printf("exit\n");//如果不设置14的响应函数,默认为关闭,所以这句不会被执行    return 0;}


司机售票员问题:


创建子进程代表售票员,父进程代表司机,同步过程如下:
售票员捕捉SIGINT(代表开车),发SIGUSR1给司机,司机打印("let's gogogo")
售票员捕捉SIGQUIT(代表停车),发SIGUSR2给司机,司机打印("stop the bus")
司机捕捉SIGTSTP(代表车到总站),发SIGUSR1给售票员,售票员打印("please get off the bus")

信号处理:

一、司机:
捕捉:SIGUSR1  SIGUSR2  SIGTSTP
忽略:SIGINT  SIGQUIT


二、售票员:
捕捉:SIGINT  SIGQUIT  SIGUSR1
忽略:SIGTSTP


demo2:

#include<unistd.h>#include<signal.h>#include<stdlib.h>#include<error.h>#include<stdio.h>int pid;//pid设置为全局,子进程中等于0,父进程中为子进程的pid//响应函数void sellersigint(int signo){    kill(getppid(),SIGUSR1);}void driversigusr1(int signo){    printf("let's gogogo\n");}void sellersigquit(int signo){    kill(getppid(),SIGUSR2);}void driversigusr2(int signo){    printf("stop the bus\n");}void sellersigusr1(int signo){    printf("please get off the bus\n");}void driversigtstp(int signo){    kill(pid,SIGUSR1);}int main(){    if((pid=fork()) == -1)    {        perror("error");        exit(1);    }        if(pid > 0)//driver    {        signal(SIGINT,SIG_IGN); //父进程(司机)忽略SIGINT信号(Ctrl + c)        signal(SIGUSR1,driversigusr1);//设置父进程对SIGUSR1信号的响应函数        signal(SIGQUIT,SIG_IGN);  //父进程(司机)忽略SIGQUIT信号(Ctrl + \)        signal(SIGUSR2,driversigusr2);  //设置父进程对SIGUSR2信号的响应函数        signal(SIGTSTP,driversigtstp);  //设置父进程(司机)对SIGSTSP信号(Ctrl + z)的响应函数        while(1);    }    else  //seller    {        signal(SIGINT, sellersigint);//设置子进程(售票员)对SIGINT信号(Ctrl + c)的响应函数        signal(SIGQUIT,sellersigquit); //设置子进程(售票员)对SIGQUIT信号(Ctrl + \)的响应函数               signal(SIGTSTP,SIG_IGN);  子进程(售票员)忽略SIGTSTP信号(Ctrl + z)        signal(SIGUSR1,sellersigusr1); 设置子进程(售票员)对SIGUSR1信号的响应函数        while(1);    }}

更加精简的demo2:

#include <stdio.h>#include <signal.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>pid_t pid;void conductor_handler(int signo);void driver_handler(int signo);int main(){    if((pid = fork()) < 0){         perror("fork error.\n");    }    else if(pid == 0){         signal(SIGTSTP,SIG_IGN);           signal(SIGINT,conductor_handler);        signal(SIGQUIT,conductor_handler);        signal(SIGUSR1,conductor_handler);        while(1){            pause();        }    }    else{          signal(SIGINT,SIG_IGN);         signal(SIGQUIT,SIG_IGN);          signal(SIGTSTP,driver_handler);        signal(SIGUSR1,driver_handler);        signal(SIGUSR2,driver_handler);        while(1){            pause();        }    }    return 0;}void conductor_handler(int signo){    switch(signo)    {    case SIGINT :        kill(getppid(),SIGUSR1);        break;    case SIGQUIT:        kill(getppid(),SIGUSR2);        break;    case SIGUSR1:        printf("Final station ,all get off.\n");        exit(0);        }}void driver_handler(int signo){    switch(signo)    {    case SIGTSTP :        kill(pid,SIGUSR1);        wait(NULL);         exit(0);    case SIGUSR1 :        printf("bus will run...\n");        break;    case SIGUSR2 :        printf("bus will stop...\n");        break;    }}


原创粉丝点击