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!
相关推荐
wj3055853787 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
abigriver7 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
wangqiaowq8 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU8 小时前
Petalinux新建自动脚本启动
linux
charlie1145141919 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
于小猿Sup9 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y9 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
不仙52011 小时前
VMware Workstation 26.0.0 在 Ubuntu 24.04 (内核 6.17.0) 上的安装与内核模块编译问题
linux·ubuntu·elasticsearch
小小编程路11 小时前
C++ 多线程与并发
java·jvm·c++
AI视觉网奇11 小时前
linux 检索库 判断库是否支持
java·linux·服务器