linux

Linux进程通信机制:管道、消息队列和共享内存

小樊
46
2025-06-16 19:10:53
栏目: 智能运维

Linux进程通信(IPC)机制允许进程之间交换数据和信息。以下是三种常见的Linux IPC机制:

1. 管道(Pipes)

定义: 管道是一种半双工的通信方式,数据只能单向流动,通常用于具有亲缘关系的进程之间(例如父子进程)。

类型

特点

示例代码

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

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

    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]); // 关闭写端
        read(pipefd[0], buffer, sizeof(buffer));
        printf("Child received: %s\n", buffer);
        close(pipefd[0]);
    } else { // 父进程
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello from parent", 20);
        close(pipefd[1]);
    }

    return 0;
}

2. 消息队列(Message Queues)

定义: 消息队列是一种进程间通信机制,允许进程发送和接收消息。消息队列中的消息有类型,可以根据类型进行选择性接收。

特点

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>

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

int main() {
    int msgid;
    key_t key = 1234;
    struct msg_buffer message;

    // 创建消息队列
    msgid = msgget(key, IPC_CREAT | 0666);
    if (msgid == -1) {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    // 发送消息
    message.msg_type = 1;
    strcpy(message.msg_text, "Hello from sender");
    if (msgsnd(msgid, &message, sizeof(message.msg_text), 0) == -1) {
        perror("msgsnd");
        exit(EXIT_FAILURE);
    }

    // 接收消息
    if (msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0) == -1) {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    printf("Received message: %s\n", message.msg_text);

    // 删除消息队列
    if (msgctl(msgid, IPC_RMID, NULL) == -1) {
        perror("msgctl");
        exit(EXIT_FAILURE);
    }

    return 0;
}

3. 共享内存(Shared Memory)

定义: 共享内存是最快的IPC机制之一,它允许多个进程访问同一块物理内存。进程可以将这块内存映射到自己的地址空间,从而实现数据共享。

特点

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

int main() {
    int shmid;
    key_t key = 1234;
    char *shmaddr;
    pid_t pid;

    // 创建共享内存段
    shmid = shmget(key, 1024, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 将共享内存段附加到进程地址空间
    shmaddr = shmat(shmid, NULL, 0);
    if (shmaddr == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 写入数据
    strcpy(shmaddr, "Hello from shared memory");

    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // 子进程
        sleep(2); // 等待父进程写入数据
        printf("Child read: %s\n", shmaddr);
        shmdt(shmaddr); // 分离共享内存段
    } else { // 父进程
        sleep(1); // 等待子进程读取数据
        printf("Parent read: %s\n", shmaddr);
        shmdt(shmaddr); // 分离共享内存段
    }

    // 删除共享内存段
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(EXIT_FAILURE);
    }

    return 0;
}

总结

选择合适的IPC机制取决于具体的应用需求和性能考虑。

0
看了该问题的人还看了