linux

Linux进程通信:管道与信号详解

小樊
95
2025-02-15 04:09:09
栏目: 智能运维

在Linux系统中,进程间通信(IPC)是一个重要的概念,它允许进程之间交换信息。管道和信号是两种常见的进程间通信机制。下面将详细介绍这两种机制的基本概念、使用场景和示例代码。

管道(Pipe)

管道是一种半双工通信方式,允许数据在进程间单向传输。管道分为两种类型:匿名管道和有名管道(FIFO)。

匿名管道

概念:匿名管道是一种在有亲缘关系的进程间(如父子进程)进行单向数据传输的通信机制,存在于内存中,通常用于临时通信。如果需要双向通信,则一般需要两个管道。

使用场景:适用于有亲缘关系的进程间的简单数据传输,例如父子进程。

示例代码

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (pid == 0) { // 子进程
        close(pipefd[1]); // 关闭写端
        char *msg = "Hello, Parent!";
        write(pipefd[1], msg, strlen(msg));
        close(pipefd[1]);
    } else { // 父进程
        close(pipefd[1]); // 关闭写端
        char buffer[100];
        read(pipefd[0], buffer, sizeof(buffer));
        printf("Received: %s
", buffer);
        close(pipefd[0]);
    }

    return 0;
}

有名管道(FIFO)

概念:有名管道是一种特殊类型的文件,用于在不相关的进程之间实现通信。与匿名管道不同,有名管道在文件系统中具有一个实际的路径名。这允许任何具有适当权限的进程打开和使用它,而不仅限于有亲缘关系的进程。

使用场景:用于本机任何两个进程间的通信,特别是当这些进程没有血缘关系时。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define FIFO "/tmp/my_fifo"

int main() {
    const char *fifopath = FIFO;
    mkfifo(fifopath, 0666); // 创建有名管道

    char buf[1024];
    int fd;

    // Server
    fd = open(fifopath, O_RDONLY);
    while (1) {
        read(fd, buf, sizeof(buf));
        printf("Received: %s
", buf);
    }
    close(fd);

    // Client
    printf("enter message: ");
    fgets(buf, sizeof(buf), stdin);
    fd = open(fifopath, O_WRONLY);
    write(fd, buf, strlen(buf) + 1);
    close(fd);

    return 0;
}

信号(Signal)

信号是一种用于进程间通信的机制,允许操作系统或一个进程向另一个进程发送简单的消息。信号主要用于传递关于系统事件的通知,例如中断请求、程序异常、或其他重要事件。

信号的种类

信号的发送与接收

信号可以通过命令行(如 kill 命令)、函数调用(如 kill() 函数)或程序内部设置信号处理函数等方式发送和接收。

示例代码

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void signalHandler(int signum) {
    printf("Received signal %d
", signum);
}

int main() {
    signal(SIGINT, signalHandler);
    while (1) {
        printf("Running...
");
        sleep(1);
    }
    return 0;
}

总结

管道和信号是Linux系统中两种重要的进程间通信机制。管道适用于有亲缘关系的进程间的数据传输,而信号则用于不相关进程间的通知和事件处理。通过合理使用这两种机制,可以有效地实现进程间的信息交换和协同工作。

0
看了该问题的人还看了