★信号是提供处理异步事件机制的软件中断。这些事情可以来自系统外部--例如系统产生中断符(通常Ctrl-C),或者来自程序或内核内部的活动,例如进程执行除以零的代码。作为一种进程间通信的基本形式,进程也可以给另一个进程发送信号。 --《linux系统编程》 ”
如上所述,信号可以实现进程间的通信。本章主要记录信号的使用方法。
产生信号的方式有很多种,比如终端驱动程序,进程,系统。
进程对于处理信号的方式,可概括为如下三种方式:
过去,当一个信号被发送后,除了知道发生了一个信号之外,处理函数对于发生了什么一无所知。现在内核可以给处理函数提供大量的上下文,甚至信号能传递用户定义的数据,跟后来更高级的IPC通信机制一样。
以上大概的记录,大概能明白信号是怎么一回事。重点是在理解信号的基础上,会使用信号实现进程间的通信,在软件设计交互时,多一个设计思路。
发送函数
通常用法,kill给进程号为pid的进程发送信号sig。
头文件 | #include <sys/types.h> #include <signal.h> |
原型 | int kill(pid_t pid, int sig) |
pid | 0 sig被发送到当前进程所在进程组中每一个进程 -1 sig被发送到每个有权限发送信号的进程(除init进程外) <-1 sig被发送到进程组为-pid的每一个进程 |
sig | 发送的信号量 |
返回值 | 0: 成功 -1:失败 |
头文件 | #include <signal.h> |
原型 | int raise(int sig) |
sig | 发送的信号量 |
返回值 | 0: 成功 -1:失败 |
接收函数
头文件 | #include <signal.h> |
原型 | typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); |
signum | 监听的信号量 |
handler | SIG_DFL: 默认的信号处理程序 SIG_IGN: 忽视该信号 自定义响应函数 |
返回值 | 该函数返回信号处理程序之前的值,当发生错误时返回 SIG_ERR。 |
功能: 设计两个C/S进程,其中一个client进程负责向server进程发送信号;server进程负责响应处理client信号。 演示:
client.cpp
#include <stdio.h>
#include <signal.h>
#include <iostream>
#include <stdlib.h>
#include "common.h"
int main(int argc, char *argv[])
{
int signo = 0;
char mode[1] = {0};
fprintf(stdout, "1: SIGUSR1\n");
fprintf(stdout, "2: SIG_TEST1\n");
fprintf(stdout, "3: default\n");
while (1) {
signo = 0;
fprintf(stdout, "Select signal to send %s: ", argv[1]);
scanf("%s", mode);
switch(mode[0]) {
case '1':
signo = SIGUSR1;
break;
case '2':
signo = SIG_TEST1;
break;
default:
signo = SIG_DEFAULT;
break;
}
//fprintf(stdout, "mode: %d %d\n", signo, SIG_DEFAULT);
kill(atoi(argv[1]), signo);
}
return 0;
}
server.cpp
#include <stdio.h>
#include <signal.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include "common.h"
void SignalHandler(int sig)
{
fprintf(stdout, "Receive signal: ");
switch(sig) {
case SIGUSR1:
fprintf(stdout, "SIGUSR1\n");
break;
case SIG_TEST1:
fprintf(stdout, "SIG_TEST1\n");
break;
default:
fprintf(stdout, "default\n");
break;
}
}
int main(int argc, char *argv[])
{
fprintf(stdout, "Pid: %d\n", getpid());
signal(SIGUSR1, SignalHandler);
signal(SIG_TEST1, SignalHandler);
signal(SIG_DEFAULT, SignalHandler);
while(1);
return 0;
}
《linux系统编程》
https://www.cnblogs.com/electronic/p/10939769.html https://blog.csdn.net/dxpqxb/article/details/78251551