在Linux系统中,进程间通信(IPC)是一种允许不同进程之间共享数据和信息的机制。管道和信号是两种常见的IPC方法。下面是对它们的详细解释:
管道是一种半双工的通信方式,通常用于具有亲缘关系的进程之间(例如父子进程)。管道分为两种类型:
无名管道(Unnamed Pipes):
创建和使用无名管道的示例:
#include <stdio.h>
#include <unistd.h>
int main() {
int pipefd[2];
pid_t pid;
char buffer[10];
// 创建管道
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) { // 子进程
close(pipefd[1]); // 关闭写端
read(pipefd[0], buffer, sizeof(buffer));
printf("Child received: %s\n", buffer);
close(pipefd[0]);
} else { // 父进程
close(pipefd[0]); // 关闭读端
write(pipefd[1], "Hello from parent", 20);
close(pipefd[1]);
}
return 0;
}
命名管道(Named Pipes,FIFOs):
创建和使用命名管道的示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
char buffer[10];
// 创建命名管道
if (mkfifo("myfifo", 0666) == -1) {
perror("mkfifo");
return 1;
}
// 打开命名管道进行读写
fd = open("myfifo", O_RDWR);
if (fd == -1) {
perror("open");
return 1;
}
// 写入数据
write(fd, "Hello from FIFO", 20);
// 读取数据
read(fd, buffer, sizeof(buffer));
printf("Read from FIFO: %s\n", buffer);
// 关闭文件描述符
close(fd);
// 删除命名管道
unlink("myfifo");
return 0;
信号是一种异步的通知机制,用于通知进程某个事件已经发生。信号可以由操作系统、其他进程或进程自身发送。常见的信号包括:
SIGINT:中断信号,通常由Ctrl+C触发。SIGTERM:终止信号,用于请求进程终止。SIGKILL:强制终止信号,无法被捕获或忽略。SIGUSR1 和 SIGUSR2:用户自定义信号。发送和处理信号的示例:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// 信号处理函数
void signal_handler(int signum) {
printf("Received signal %d\n", signum);
}
int main() {
// 注册信号处理函数
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
printf("Process is running. Press Ctrl+C to send SIGINT or kill -TERM <pid> to send SIGTERM.\n");
// 主进程循环
while (1) {
sleep(1);
}
return 0;
}
在这个示例中,当进程接收到SIGINT或SIGTERM信号时,会调用signal_handler函数进行处理。
这两种IPC机制在Linux系统中非常常用,掌握它们对于编写高效、可靠的系统程序非常重要。