Linux进程间通信主要通过信号(signal)、管道(pipe)、消息队列(message queue)、共享内存(shared memory)、Socket(socket)等机制来实现。其中,信号是最基本、最常用的进程间通信方式之一。
一、Linux信号的概念与基本特征:
信号是 Linux/Linux POSIX 系统中一种软件中断,作用是向进程发送通知,进程可以捕捉、处理信号,改变进程执行的行为。Linux系统支持 31 种不同的信号,每一种信号都有不同的含义和操作,可以用来实现进程间通信、进程控制等功能。
Linux信号的基本特征包括:信号的名称、信号的编号、信号的产生方式(使用 kill 指令、硬件/软件中断等方式)、信号的作用、信号的默认处理方式等。
另外,还需要注意的是,进程一旦接收到信号,会立刻中断当前进程的正常流程,转而去执行对应的信号处理程序。这意味着,进程接收到信号后,可能会对已有的业务流程产生影响,需要谨慎处理。
二、Linux常用信号及作用:
-
SIGHUP(1):流程控制,通知进程重新读取其配置文件,重新初始化进程状态;
-
SIGINT(2):流程控制,通知进程中断当前(如键入 Ctrl+C);
-
SIGQUIT(3):流程控制,通知进程中止并制作内核转储(dump core);
-
SIGKILL(9):强制终止信号,通知进程立即终止,并且不允许进程捕捉、处理这个信号;
-
SIGUSR1(10):用户定义的信号1,可以自由使用,不会被操作系统使用;
-
SIGUSR2(12):用户定义的信号2,可以自由使用,不会被操作系统使用;
三、Linux中信号的使用:
对于 Linux 信号的使用,对应的实现方式有多种,其中比较常见的方式是通过系统调用signal()
和 sigaction()
函数来接收和处理信号。
例如,我们可以使用 signal()
函数来定义信号处理程序,示范代码如下:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void my_signal_handler(int s)
{
printf("Caught signal %d\n", s);
}
int main(void)
{
signal(SIGINT, my_signal_handler);
while(1) {
printf("Hello World!\n");
sleep(1);
}
return 0;
}
这里,我们定义了一个名为 my_signal_handler
的信号处理程序,并通过 signal(SIGINT, my_signal_handler)
设置了 SIGINT 信号的处理方式。在程序运行的过程中,如果用户键入了 Ctrl+C,就会触发 SIGINT 信号,进而执行 my_signal_handler
函数内的处理流程。
另一种定义信号处理程序的方式是使用 sigaction()
函数,示范代码如下:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void my_signal_handler(int s)
{
printf("Caught signal %d\n", s);
}
int main(void)
{
struct sigaction sa, old_sa;
sa.sa_handler = my_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, &old_sa);
while(1) {
printf("Hello World!\n");
sleep(1);
}
return 0;
}
这里我们使用 struct sigaction
结构体定义了一个新的信号处理程序,并通过 sigaction(SIGINT, &sa, &old_sa)
将 SIGINT 信号的处理方式改为了新的程序处理方式。通过这种设置,我们可以更加灵活地控制信号的处理方式,比如可以在新的处理程序中指定自定义的处理流程、向处理程序传递参数等。
以上是对 Linux 常用信号的概念、作用和使用方法的一个完整攻略。对于信号的使用,我们可以通过编写自定义的信号处理程序来实现自己的进程间通信、进程控制等功能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Linux常用信号(进程间通信)及其含义 - Python技术站