Linux 进程间通信

Linux进程间通信

进程间通信(IPC,Inter-Process Communication)在 Linux 下常用的方法包括:

1)管道(Pipe)

2)有名管道(FIFO)

3)消息队列(Message Queue)

4)共享内存(Shared Memory)

5)信号量(Semaphore)

6)套接字(Socket)

1. 管道(Pipe)

管道是一种最基本的 IPC 方法,适用于有亲缘关系的进程之间通信。

管道(Pipe)参考代码

bash 复制代码
#include <iostream>
#include <unistd.h>
#include <cstring>

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

    //创建管道
    ret = pipe(pipefd);
    std::cout <<"ret = " << ret << std::endl;
    if (ret == -1) { //当ret为-1时,说明pipe函数发生错误执行失败
        perror("pipe");
        return 1;
    }

    pid = fork();  //创建子进程

    std::cout << "pid= "  << pid << std::endl;
    if (pid < 0) {
        perror("fork");
        return 1;
    }

    if (pid == 0) {  // 子进程
        close(pipefd[0]);  // 关闭读端
        const char* message = "Hello from child process!";
        write(pipefd[1], message, strlen(message) + 1);
        close(pipefd[1]);  // 关闭写端
    } else {  // 父进程
        close(pipefd[1]);  // 关闭写端
        read(pipefd[0], buffer, sizeof(buffer));
        std::cout << "Parent received: " << buffer << std::endl;
        close(pipefd[0]);  // 关闭读端
    }

    return 0;
}

管道(Pipe)输出结果

cpp 复制代码
ret = 0
pid= 26087
pid= 0
Parent received: Hello from child process!

2. 有名管道(FIFO)

适用于不相关的进程。

有名管道(FIFO)参考代码

cpp 复制代码
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>

#define FIFO_PATH "/tmp/myfifo"

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

    // 创建有名管道
    if (mkfifo(FIFO_PATH, 0666) == -1) {
        perror("mkfifo");
    }

    pid = fork();  // 创建子进程
    if (pid < 0) {
        perror("fork");
        return 1;
    }

    if (pid == 0) {  // 子进程
        int fd = open(FIFO_PATH, O_WRONLY);
        const char* message = "Hello from child process!";
        write(fd, message, strlen(message) + 1);
        close(fd);
    } else {  // 父进程
        int fd = open(FIFO_PATH, O_RDONLY);
        read(fd, buffer, sizeof(buffer));
        std::cout << "Parent received: " << buffer << std::endl;
        close(fd);
        unlink(FIFO_PATH);  // 删除 FIFO
    }

    return 0;
}

有名管道(FIFO)输出结果

cpp 复制代码
Parent received: Hello from child process!

3. 消息队列(Message Queue)

消息队列适合于复杂的通信需求。

消息队列(Message Queue)参考代码

cpp 复制代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>

struct Message {
    long msg_type;
    char msg_text[100];
};

int main() {
    pid_t pid;
    key_t key = ftok("progfile", 65);
    int msgid = msgget(key, 0666 | IPC_CREAT);
    Message message;
    
    pid = fork(); // 创建子进程
    if (pid == 0) {  // 子进程
        message.msg_type = 1;
        strcpy(message.msg_text, "Hello from child process!");
        msgsnd(msgid, &message, sizeof(message.msg_text), 0);
    } else {  // 父进程
        msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0);
        std::cout << "Parent received: " << message.msg_text << std::endl;
        msgctl(msgid, IPC_RMID, NULL);  // 删除消息队列
    }

    return 0;
}

消息队列(Message Queue)输出结果

cpp 复制代码
Parent received: Hello from child process!

4. 共享内存(Shared Memory)

共享内存是最快的 IPC 方法,但需要同步机制。

有名管道(FIFO)参考代码

cpp 复制代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <unistd.h>

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid = shmget(key, 1024, 0666 | IPC_CREAT);
    char* str = (char*)shmat(shmid, (void*)0, 0);
    pid_t pid;
    
    pid = fork(); // 创建子进程
    if (pid == 0) {  // 子进程
        strcpy(str, "Hello from child process!");
        shmdt(str);
    } else {  // 父进程
        sleep(1);  // 确保子进程写入完成
        std::cout << "Parent received: " << str << std::endl;
        shmdt(str);
        shmctl(shmid, IPC_RMID, NULL);  // 删除共享内存
    }

    return 0;
}

有名管道(FIFO)输出结果

cpp 复制代码
Parent received: Hello from child process!

5. 信号量(Semaphore)

信号量主要用于同步。

信号量(Semaphore)参考代码

cpp 复制代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

void semaphore_op(int semid, int op) {
    struct sembuf sop = {0, static_cast<short> (op), 0};
    semop(semid, &sop, 1);
}

int main() {
    key_t key = ftok("semfile", 65);
    int semid = semget(key, 1, 0666 | IPC_CREAT);
    semctl(semid, 0, SETVAL, 0);
    pid_t pid;

    pid = fork();  //创建子进程
    if (pid == 0) {  // 子进程
        std::cout << "Child: Writing data...\n";
        sleep(2);
        semaphore_op(semid, 1);  // 信号量加 1
        std::cout << "Child: Data written.\n";
    } else {  // 父进程
        std::cout << "Parent: Waiting for data...\n";
        semaphore_op(semid, -1);  // 等待信号量变为 0
        std::cout << "Parent: Data received.\n";
        semctl(semid, 0, IPC_RMID);  // 删除信号量
    }

    return 0;
}

`

信号量(Semaphore)输出结果

cpp 复制代码
Parent: Waiting for data...
Child: Writing data...
Child: Data written.
Parent: Data received.

6. 套接字(Socket)

适用于网络通信或本地进程间通信。

套接字(Socket)参考代码

cpp 复制代码
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>

int main() {
    int sv[2];  // Socket pair
    char buffer[1024];
    pid_t pid;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
        perror("socketpair");
        return 1;
    }
    
    pid = fork(); // 创建子进程
    if (pid == 0) {  // 子进程
        close(sv[0]);
        const char* message = "Hello from child process!";
        write(sv[1], message, strlen(message) + 1);
        close(sv[1]);
    } else {  // 父进程
        close(sv[1]);
        read(sv[0], buffer, sizeof(buffer));
        std::cout << "Parent received: " << buffer << std::endl;
        close(sv[0]);
    }

    return 0;
}

套接字(Socket)输出结果

cpp 复制代码
Parent received: Hello from child process!
相关推荐
starvapour10 分钟前
Ubuntu部署gitlab频繁出现502的问题
linux·ubuntu·gitlab
zhangfeng11331 小时前
ps aux讲解,结合国家超算中心 hpc apptainer
linux·服务器·网络
不负岁月无痕1 小时前
C++ 模板核心内容与高频面试题汇总
java·开发语言·c++
夜月yeyue1 小时前
STM32 DMA 双缓冲采样
linux·stm32·单片机·嵌入式硬件·系统架构
ScilogyHunter1 小时前
Buildroot完全指南:从入门到实战
linux·嵌入式·buildroot
毕竟是shy哥1 小时前
Claude Code 接入 DeepSeek 保姆级教程,WSL/Linux 通用
linux·安装教程·codex·deepseek·claude code·openclaw
无限进步_1 小时前
从零实现一个迷你Shell——深入理解Linux命令行解释器
linux·运维·服务器·开发语言·c++·chrome
fpcc2 小时前
工具使用——CMake中的函数和宏
c++·cmake
happymaker06262 小时前
Linux常见命令总结
linux·运维·服务器
lbb 小魔仙2 小时前
【Linux】DevOps 工程师必备:Linux 自动化脚本与高效工具链整合
linux·自动化·devops