用信号的知识实现司机和售票员问题。
1)售票员捕捉SIGINT(代表开车)信号,向司机发送SIGUSR1信号,司机打印(let's gogogo)
2)售票员捕捉SIGQUIT(代表停车)信号,向司机发送SIGUSR2信号,司机打印(stop the bus)
3)司机捕捉SIGTSTP(代表到达终点站)信号,向售票员发送SIGUSR1信号,售票员打印(please get off the bus)
4)司机等待售票员下车,之后司机再下车。
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>pid_t pid; // 全局变量,用于存储子进程的进程 ID// 子进程(售货员)的信号处理函数
void saler(int sig)
{if (sig == SIGINT){// 收到 SIGINT 信号时,向父进程发送 SIGUSR1 信号if (kill(getppid(), SIGUSR1) == -1) {perror("kill SIGUSR1 error");}}else if (sig == SIGQUIT){// 收到 SIGQUIT 信号时,向父进程发送 SIGUSR2 信号if (kill(getppid(), SIGUSR2) == -1) {perror("kill SIGUSR2 error");}}else if (sig == SIGUSR1){// 收到 SIGUSR1 信号时,打印消息并退出printf("pls get off the bus!\n");exit(0);}
}// 父进程(司机)的信号处理函数
void driver(int sig)
{if (sig == SIGUSR1)// 收到 SIGUSR1 信号时,打印开始消息printf("let's gogogo!!!~~\n");else if (sig == SIGUSR2)// 收到 SIGUSR2 信号时,打印停止消息printf("stop the bus!\n");else if (sig == SIGTSTP){// 收到 SIGTSTP 信号时,向子进程发送 SIGUSR1 信号,并等待子进程退出if (kill(pid, SIGUSR1) == -1) {perror("kill SIGUSR1 error");}if (wait(NULL) == -1) {perror("wait error");}exit(0);}
}int main(int argc, char const *argv[])
{pid = fork(); // 创建子进程if (pid < 0){perror("fork error");return -1;}else if (pid == 0){// 子进程(售货员)printf("I am saler!\n");struct sigaction sa;sa.sa_handler = saler; // 设置信号处理函数sigemptyset(&sa.sa_mask); // 清空信号集sa.sa_flags = 0; // 没有特殊标志// 设置信号处理sigaction(SIGINT, &sa, NULL);sigaction(SIGQUIT, &sa, NULL);sigaction(SIGUSR1, &sa, NULL);// 忽略 SIGTSTP 信号sa.sa_handler = SIG_IGN;sigaction(SIGTSTP, &sa, NULL);}else{// 父进程(司机)printf("I am driver!\n");struct sigaction sa;sa.sa_handler = driver; // 设置信号处理函数sigemptyset(&sa.sa_mask); // 清空信号集sa.sa_flags = 0; // 没有特殊标志// 设置信号处理sigaction(SIGUSR1, &sa, NULL);sigaction(SIGUSR2, &sa, NULL);sigaction(SIGTSTP, &sa, NULL);// 忽略 SIGINT 和 SIGQUIT 信号sa.sa_handler = SIG_IGN;sigaction(SIGINT, &sa, NULL);sigaction(SIGQUIT, &sa, NULL);}while (1)pause(); // 等待信号return 0;
}