进程间的通信方式有哪些

在操作系统中,进程间通信(IPC,Inter-Process Communication)是指在独立进程之间交换数据或消息的机制。由于不同进程具有独立的地址空间,因此 IPC 机制必须依赖内核或特定工具来实现数据共享和同步。

以下是常见的 6种进程间通信方式,每种方法都有其适用场景和特点:


🔹 1. 管道 (Pipe)

➤ 原理

  • 管道是一种半双工(单向)通信机制,数据只能沿一个方向流动。
  • 通信的进程必须具有亲缘关系(如父子进程)。

➤ 特点

✅ 简单易用,基于文件描述符;
✅ 仅支持单向通信,数据流向固定;
✅ 适用于父子进程之间的通信;

➤ 示例代码 (C - pipe())

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

int main() {
    int fd[2];
    char buffer[100];

    pipe(fd);  // 创建管道

    if (fork() == 0) {  // 子进程
        close(fd[0]);  // 关闭读端
        write(fd[1], "Hello from child!", 18);
    } else {  // 父进程
        close(fd[1]);  // 关闭写端
        read(fd[0], buffer, sizeof(buffer));
        printf("父进程接收数据: %s\n", buffer);
    }

    return 0;
}

🔹 2. 命名管道 (Named Pipe / FIFO)

➤ 原理

  • 命名管道是一种改进版的管道,支持无亲缘关系的进程通信
  • FIFO 以文件形式存在,数据通过文件路径传输。

➤ 特点

✅ 可用于任意进程
✅ 数据具有顺序性,遵循先进先出 (FIFO);
✅ 支持持久化,FIFO 文件即使无进程使用仍存在;

➤ 示例代码 (C - mkfifo())

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

#define FIFO_PATH "/tmp/my_fifo"

int main() {
    mkfifo(FIFO_PATH, 0666);  // 创建命名管道

    if (fork() == 0) {  // 子进程
        int fd = open(FIFO_PATH, O_WRONLY);
        write(fd, "Hello from child!", 18);
        close(fd);
    } else {  // 父进程
        char buffer[100];
        int fd = open(FIFO_PATH, O_RDONLY);
        read(fd, buffer, sizeof(buffer));
        printf("父进程接收数据: %s\n", buffer);
        close(fd);
    }

    return 0;
}

🔹 3. 消息队列 (Message Queue)

➤ 原理

  • 消息队列是由内核维护的链表结构,用于存储消息,支持消息的优先级

➤ 特点

✅ 数据以消息为单位,每条消息独立;
✅ 支持非亲缘进程
✅ 消息具有持久性(即使发送进程退出,消息仍可被接收进程获取)。

➤ 示例代码 (Linux - msgsnd() / msgrcv())

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

#define MSG_KEY 1234

typedef struct message {
    long msg_type;
    char msg_text[100];
} message;

int main() {
    int msgid = msgget(MSG_KEY, 0666 | IPC_CREAT);
    
    if (fork() == 0) {  // 子进程
        message msg = {1, "Hello from child!"};
        msgsnd(msgid, &msg, sizeof(msg.msg_text), 0);
    } else {  // 父进程
        message msg;
        msgrcv(msgid, &msg, sizeof(msg.msg_text), 1, 0);
        printf("父进程接收数据: %s\n", msg.msg_text);
        msgctl(msgid, IPC_RMID, NULL);  // 删除消息队列
    }

    return 0;
}

🔹 4. 共享内存 (Shared Memory)

➤ 原理

  • 共享内存是将一块内存映射到多个进程的地址空间中,速度最快
  • 需要借助同步机制(如信号量互斥锁)确保数据安全。

➤ 特点

✅ 速度最快,直接访问内存;
✅ 支持大数据传输;
✅ 需借助同步机制避免数据竞争;

➤ 示例代码 (Linux - shmget() / shmat())

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

#define SHM_KEY 1234

int main() {
    int shmid = shmget(SHM_KEY, 1024, 0666 | IPC_CREAT);
    char* str = (char*) shmat(shmid, NULL, 0);  // 映射到内存

    if (fork() == 0) {  // 子进程
        strcpy(str, "Hello from child!");
    } else {  // 父进程
        sleep(1);  // 等待子进程写入
        printf("父进程接收数据: %s\n", str);
        shmctl(shmid, IPC_RMID, NULL);  // 删除共享内存
    }

    return 0;
}

🔹 5. 信号 (Signal)

➤ 原理

  • 信号是异步通信机制,通常用于通知进程特定事件的发生。
  • 信号无需建立连接,直接由内核触发。

➤ 特点

✅ 轻量级,系统调用简单;
✅ 适用于事件通知(如 Ctrl+C、超时提醒);
✅ 不适合大数据传输;

➤ 示例代码 (C - signal())

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

void signalHandler(int signum) {
    printf("收到信号: %d\n", signum);
}

int main() {
    signal(SIGINT, signalHandler);  // 捕获 Ctrl+C 信号
    while (1) {
        printf("等待信号...\n");
        sleep(2);
    }
    return 0;
}

🔹 6. 套接字 (Socket)

➤ 原理

  • 套接字是一种全双工的通信机制,支持本地及网络中的进程通信。

➤ 特点

✅ 适用于分布式系统远程进程通信
✅ 提供TCP/UDP两种传输模式;
✅ 复杂度较高,适用于复杂场景;

➤ 示例代码 (C - socket() / bind() / send() / recv())

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main() {
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    listen(server_fd, 3);

    int client_fd = accept(server_fd, NULL, NULL);
    send(client_fd, "Hello from server", 18, 0);

    return 0;
}

📝 对比总结

通信方式数据流向速度适用场景
管道 (Pipe)单向快速父子进程间快速传输小量数据
命名管道 (FIFO)单向快速无关进程间的快速数据交换
消息队列 (Message Queue)双向中等带有优先级的消息传递
共享内存 (Shared Memory)双向极快大量数据传输
信号 (Signal)单向快速异步事件通知
套接字 (Socket)双向较慢网络和本地进程间通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值