Linux进程间通信怎么实现

来源:Nodejs社区作者:长沙网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《Linux进程间通信怎么实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Linux进程间通信怎么实现》有用,将其分享出去将是对创作者最好的鼓励。

Linux进程间通信是操作系统中多进程协同工作的基础能力,不同的进程需要在隔离的内存空间中完成数据交换、状态通知等操作,就需要依赖系统提供的各类通信机制。这些机制各有特点,适配不同的业务场景,开发者可以根据通信的实时性、数据量、进程关系等需求选择对应的实现方式。

常见Linux进程间通信方式

1. 管道(Pipe)

管道是最基础的进程间通信方式,分为匿名管道和命名管道两种。匿名管道只能用于有亲缘关系的进程之间通信,比如父子进程;命名管道可以用于无亲缘关系的进程之间通信,在文件系统中存在对应的管道文件。

匿名管道的使用示例:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

int main() {
    int pipe_fd[2];
    pid_t pid;
    char write_buf[] = "Hello from parent process";
    char read_buf[1024];

    // 创建匿名管道
    if (pipe(pipe_fd) == -1) {
        perror("pipe create failed");
        return 1;
    }

    pid = fork();
    if (pid < 0) {
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        // 子进程:关闭写端,从读端读取数据
        close(pipe_fd[1]);
        int len = read(pipe_fd[0], read_buf, sizeof(read_buf) - 1);
        if (len > 0) {
            read_buf[len] = '';
            printf("Child process read: %sn", read_buf);
        }
        close(pipe_fd[0]);
    } else {
        // 父进程:关闭读端,向写端写入数据
        close(pipe_fd[0]);
        write(pipe_fd[1], write_buf, strlen(write_buf));
        close(pipe_fd[1]);
        wait(NULL); // 等待子进程结束
    }
    return 0;
}

2. 消息队列(Message Queue)

消息队列是内核维护的消息链表,进程可以向队列中发送指定类型的消息,也可以按类型读取消息,支持无亲缘关系的进程之间通信,消息读取后不会自动删除,需要显式操作。

消息队列简单使用示例:

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

// 定义消息结构体
struct msg_buffer {
    long msg_type;
    char msg_text[100];
};

int main() {
    key_t key = ftok("msgqueue", 65); // 生成唯一key
    int msgid = msgget(key, 0666 | IPC_CREAT); // 创建消息队列

    struct msg_buffer message;
    message.msg_type = 1;
    strcpy(message.msg_text, "Test message from process");

    // 发送消息
    msgsnd(msgid, &message, sizeof(message.msg_text), 0);
    printf("Message sent to queuen");

    // 读取消息
    msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0);
    printf("Message received: %sn", message.msg_text);

    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
    return 0;
}

3. 共享内存(Shared Memory)

共享内存是效率最高的进程间通信方式,内核将同一块物理内存映射到多个进程的虚拟地址空间,进程可以直接读写这块内存,不需要内核做数据拷贝。通常需要配合信号量等机制实现同步,避免读写冲突。

共享内存使用示例:

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

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid = shmget(key, 1024, 0666 | IPC_CREAT); // 创建共享内存段

    // 附加共享内存到进程地址空间
    char *str = (char*) shmat(shmid, NULL, 0);

    // 写入数据到共享内存
    strcpy(str, "Hello shared memory");
    printf("Data written to shared memory: %sn", str);

    // 分离共享内存
    shmdt(str);

    // 读取端可以重新附加共享内存读取数据,最后删除共享内存段
    // shmctl(shmid, IPC_RMID, NULL);
    return 0;
}

4. 信号量(Semaphore)

信号量主要用于进程间的同步和互斥,本身不传输数据,而是通过计数器控制多个进程对共享资源的访问。常见的信号量有System V信号量和POSIX信号量,下面以System V信号量为例。

#include <stdio.h>
#include <sys/sem.h>
#include <unistd.h>

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main() {
    key_t key = ftok("semfile", 65);
    int semid = semget(key, 1, 0666 | IPC_CREAT); // 创建1个信号量

    union semun arg;
    arg.val = 1; // 初始化信号量值为1
    semctl(semid, 0, SETVAL, arg);

    struct sembuf sb;
    sb.sem_num = 0;
    sb.sem_flg = 0;

    // P操作:申请资源,信号量减1
    sb.sem_op = -1;
    semop(semid, &sb, 1);
    printf("Process get resourcen");

    sleep(2); // 模拟资源使用

    // V操作:释放资源,信号量加1
    sb.sem_op = 1;
    semop(semid, &sb, 1);
    printf("Process release resourcen");

    // 删除信号量
    semctl(semid, 0, IPC_RMID);
    return 0;
}

5. 套接字(Socket)

套接字不仅可以用于网络通信,也可以用于本地进程间通信,分为网络套接字和Unix域套接字。Unix域套接字用于同一台机器上的进程通信,效率比网络套接字更高,支持无亲缘关系的进程之间通信。

Unix域套接字服务端示例:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>

int main() {
    int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    struct sockaddr_un addr;
    addr.sun_family = AF_UNIX;
    strcpy(addr.sun_path, "/tmp/unix_socket_test");

    bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
    listen(server_fd, 5);

    int client_fd = accept(server_fd, NULL, NULL);
    char buf[1024];
    int len = read(client_fd, buf, sizeof(buf) - 1);
    if (len > 0) {
        buf[len] = '';
        printf("Server received: %sn", buf);
    }

    close(client_fd);
    close(server_fd);
    unlink("/tmp/unix_socket_test");
    return 0;
}

不同通信方式的选择建议

可以根据实际需求选择合适的进程间通信方式:

  • 如果是父子进程之间简单的单向数据传输,优先选择匿名管道
  • 如果需要无亲缘关系进程之间传输结构化消息,可选择消息队列
  • 如果需要传输大量数据,追求最高效率,选择共享内存配合信号量同步
  • 如果需要跨机器或者本地进程之间通用通信,选择套接字
  • 如果只需要进程同步,不需要传输数据,选择信号量
通信方式适用场景效率是否支持无亲缘关系进程
匿名管道父子进程单向数据传输中等
命名管道无亲缘关系进程简单数据传输中等
消息队列结构化消息传输中等
共享内存大量数据高速传输最高
信号量进程同步互斥
Unix域套接字本地通用进程通信较高

Linux进程间通信pipeshared_memorysocket修改时间:2026-07-03 12:37:05

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。