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!
相关推荐
木子.李3471 小时前
排序算法总结(C++)
c++·算法·排序算法
freyazzr2 小时前
C++八股 | Day2 | atom/函数指针/指针函数/struct、Class/静态局部变量、局部变量、全局变量/强制类型转换
c++
Gaoithe2 小时前
ubuntu 端口复用
linux·运维·ubuntu
fpcc3 小时前
跟我学c++中级篇——理解类型推导和C++不同版本的支持
开发语言·c++
德先生&赛先生3 小时前
Linux编程:1、文件编程
linux
程序猿小D3 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
终焉代码4 小时前
STL解析——list的使用
开发语言·c++
DevangLic4 小时前
【 *p取出内容 &a得到地址】
c++
鑫鑫向栄4 小时前
[蓝桥杯]修改数组
数据结构·c++·算法·蓝桥杯·动态规划
鑫鑫向栄4 小时前
[蓝桥杯]带分数
数据结构·c++·算法·职场和发展·蓝桥杯