linux

Linux进程通信:如何实现管道通信

小樊
50
2025-10-07 10:23:37
栏目: 智能运维

在Linux中,管道(pipe)是一种用于在不同进程之间传输数据的机制。管道通信通常分为两种类型:匿名管道(unnamed pipe)和命名管道(named pipe,也称为FIFO)。下面分别介绍这两种管道的实现方法。

匿名管道(Unnamed Pipe)

匿名管道是一种半双工的通信方式,只能在具有亲缘关系的进程之间使用(例如父子进程)。匿名管道通过pipe()系统调用创建。

创建匿名管道

#include <unistd.h>

int pipe(int pipefd[2]);

pipe()函数接受一个包含两个整数的数组pipefdpipefd[0]用于读取数据,pipefd[1]用于写入数据。

示例代码

以下是一个简单的示例,展示了如何使用匿名管道在父子进程之间传输数据:

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

int main() {
    int pipefd[2];
    pid_t pid;
    char buffer[1024];

    // 创建匿名管道
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // 子进程
        close(pipefd[1]); // 关闭写端

        // 从管道读取数据
        ssize_t bytes_read = read(pipefd[0], buffer, sizeof(buffer));
        if (bytes_read > 0) {
            printf("Child received: %s\n", buffer);
        }

        close(pipefd[0]); // 关闭读端
        exit(EXIT_SUCCESS);
    } else { // 父进程
        close(pipefd[0]); // 关闭读端

        // 向管道写入数据
        const char *message = "Hello from parent!";
        ssize_t bytes_written = write(pipefd[1], message, strlen(message) + 1);
        if (bytes_written > 0) {
            printf("Parent sent: %s\n", message);
        }

        close(pipefd[1]); // 关闭写端
        wait(NULL); // 等待子进程结束
    }

    return 0;
}

命名管道(Named Pipe,FIFO)

命名管道是一种全双工的通信方式,可以在任意进程之间使用。命名管道通过mkfifo()系统调用创建。

创建命名管道

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

mkfifo()函数接受两个参数:pathname是命名管道的路径名,mode是命名管道的权限模式。

示例代码

以下是一个简单的示例,展示了如何使用命名管道在两个进程之间传输数据:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>

int main() {
    const char *fifo_path = "/tmp/myfifo";
    int fd;
    char buffer[1024];

    // 创建命名管道
    if (mkfifo(fifo_path, 0666) == -1) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }

    // 打开命名管道
    fd = open(fifo_path, O_RDWR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 向命名管道写入数据
    const char *message = "Hello from process!";
    ssize_t bytes_written = write(fd, message, strlen(message) + 1);
    if (bytes_written > 0) {
        printf("Process sent: %s\n", message);
    }

    // 从命名管道读取数据
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read > 0) {
        printf("Process received: %s\n", buffer);
    }

    close(fd); // 关闭命名管道
    unlink(fifo_path); // 删除命名管道

    return 0;
}

通过以上示例,你可以了解如何在Linux中使用匿名管道和命名管道实现进程间通信。

0
看了该问题的人还看了