当前位置: 首页 > news >正文

Linux 进程与线程间通信方式及应用分析

Linux 进程与线程间通信方式及应用分析

文章目录

      • Linux 进程与线程间通信方式及应用分析
    • 1. 管道(Pipe)
      • 1.1 匿名管道(Anonymous Pipe)
        • 示例代码:
        • 结果:
      • 1.2 命名管道(FIFO)
        • 示例代码:
        • 结果:
      • 优缺点:
    • 2. 消息队列(Message Queue)
      • 示例代码:
        • 结果:
      • 优缺点:
    • 3. 共享内存(Shared Memory)
      • 示例代码:
        • 结果:
      • 优缺点:
    • 4. 信号(Signal)
      • 示例代码:
        • 结果:
      • 优缺点:
    • 5. 套接字(Socket)
      • 示例代码:
        • 结果:
      • 优缺点:
    • 总结

1. 管道(Pipe)

管道是 Linux 中最基础的进程间通信方式,通常用于父子进程之间的数据传输。它可以分为匿名管道和命名管道两种。

1.1 匿名管道(Anonymous Pipe)

匿名管道是最常见的进程间通信方式,通常由父子进程使用。它是通过内核缓冲区进行数据传输的,通信是单向的。

示例代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main() {int pipe_fd[2];pid_t pid;char write_msg[] = "Hello from parent";char read_msg[100];// 创建管道if (pipe(pipe_fd) == -1) {perror("Pipe failed");return 1;}pid = fork();  // 创建子进程if (pid < 0) {perror("Fork failed");return 1;}if (pid > 0) {  // 父进程close(pipe_fd[0]);  // 关闭读端write(pipe_fd[1], write_msg, strlen(write_msg) + 1);close(pipe_fd[1]);  // 关闭写端} else {  // 子进程close(pipe_fd[1]);  // 关闭写端read(pipe_fd[0], read_msg, sizeof(read_msg));printf("Child process received: %s\n", read_msg);close(pipe_fd[0]);  // 关闭读端}return 0;
}
结果:

父进程通过管道写入数据,子进程通过管道读取数据。输出为:

Child process received: Hello from parent

1.2 命名管道(FIFO)

命名管道与匿名管道类似,但它允许不同的进程进行通信,即使它们没有亲缘关系。可以通过文件路径进行标识。

示例代码:
# 在终端中创建命名管道
mkfifo /tmp/myfifo# 终端1
echo "Message from terminal1" > /tmp/myfifo# 终端2
cat /tmp/myfifo
结果:

终端2会输出从终端1发送的消息。

优缺点:

优点缺点应用场景
简单易用,适合父子进程通信。只能在父子进程间通信,单向通信。父子进程间简单的数据传递。

2. 消息队列(Message Queue)

消息队列是 Linux 提供的一种进程间通信机制,它允许进程之间通过消息进行通信。消息队列的特点是能够存储消息,且消息传递是异步的。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct msg_buffer {long msg_type;char msg_text[100];
};int main() {key_t key;int msgid;struct msg_buffer message;// 创建消息队列key = ftok("progfile", 65);msgid = msgget(key, 0666 | IPC_CREAT);message.msg_type = 1;strcpy(message.msg_text, "Hello from message queue");// 发送消息msgsnd(msgid, &message, sizeof(message), 0);printf("Message sent: %s\n", message.msg_text);// 接收消息msgrcv(msgid, &message, sizeof(message), 1, 0);printf("Message received: %s\n", message.msg_text);// 删除消息队列msgctl(msgid, IPC_RMID, NULL);return 0;
}
结果:

进程通过消息队列发送和接收消息,成功传递数据。

优缺点:

优点缺点应用场景
支持异步通信,消息可以排队。有可能阻塞,消息队列最大长度有限。高并发的进程间异步通信。

3. 共享内存(Shared Memory)

共享内存是最有效的进程间通信方式,允许多个进程共享一块内存区域。它的速度非常快,但需要考虑同步问题。

示例代码:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>int main() {key_t key = 1234;int shmid;char *shm_ptr;// 创建共享内存shmid = shmget(key, 1024, 0666 | IPC_CREAT);shm_ptr = (char*) shmat(shmid, NULL, 0);// 写数据到共享内存strcpy(shm_ptr, "Hello from shared memory");// 读取共享内存数据printf("Data read from shared memory: %s\n", shm_ptr);// 分离共享内存shmdt(shm_ptr);// 删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
}
结果:

共享内存区的数据能够在多个进程间共享,提供高效的通信。

优缺点:

优点缺点应用场景
速度快,效率高。需要额外的同步机制,如互斥锁。大量数据交换的高效通信。

4. 信号(Signal)

信号是一种简单的进程间通信方式,适用于处理事件或通知其他进程发生了某些事情。

示例代码:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>void signal_handler(int signum) {printf("Signal %d received!\n", signum);
}int main() {signal(SIGINT, signal_handler);  // 捕获 SIGINT 信号printf("Press Ctrl+C to send SIGINT signal...\n");while (1) {sleep(1);}return 0;
}
结果:

按下 Ctrl+C 发送 SIGINT 信号后,程序将捕获并响应该信号。

优缺点:

优点缺点应用场景
简单易用,适合事件驱动的场景。仅能传递简单的事件信息。处理异步事件和信号通知。

5. 套接字(Socket)

套接字是跨进程(包括不同机器)的通信机制,可以在不同的进程间传递复杂的数据。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080int main() {int server_fd, new_socket;struct sockaddr_in address;char *message = "Hello from server";// 创建 socketserver_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd == 0) {perror("Socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定 socketif (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("Bind failed");exit(EXIT_FAILURE);}// 监听if (listen(server_fd, 3) < 0) {perror("Listen failed");exit(EXIT_FAILURE);}// 接受连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&address)) < 0) {perror("Accept failed");exit(EXIT_FAILURE);}send(new_socket, message, strlen(message), 0);printf("Message sent\n");return 0;
}
结果:

使用套接字实现了服务器和客户端间的通信。

优缺点:

优点缺点应用场景
支持跨主机通信,数据传输灵活。编程较为复杂,需要理解网络协议。远程进程间通信或分布式系统。

总结

通信方式优点缺点应用场景
管道简单易用,适合父子进程通信。只能单向通信,无法跨进程。父子进程间数据传输。
消息队列支持异步通信,消息排队。阻塞问题,消息队列容量有限。高并发的异步通信。
共享内存高效,速度快。需要同步机制。高效数据交换。
信号简单易用,适合事件通知。只能传递简单信息。异步事件通知。
套接字支持跨主机通信,灵活多变。编程复杂,需理解网络协议。分布式系统,远程进程通信。

这些通信方式在实际开发中都有着广泛的应用,选择合适的通信方式可以有效提高系统的性能和可维护性。

相关文章:

  • 什么是Manus,国内用户如何订阅Manus
  • 论文阅读HARIVO: Harnessing Text-to-Image Models for Video Generation
  • 【论文速递】2025年06周 (Robotics/Embodied AI/LLM)
  • 随机过程,相关函数的一个例题|柯尔莫哥洛夫存在定理
  • 17.整体代码讲解
  • 动态规划-零钱兑换
  • 自动驾驶最新算法进展
  • (二十九)安卓开发中DataBinding 和 ViewBinding详解
  • Ubuntu 系统下安装和使用性能分析工具 perf
  • 人工智能在慢病管理中的具体应用全集:从技术落地到场景创新
  • Uniapp:创建项目
  • flutter 专题 六十六 Flutter Dio包网络请求抓包解决方案
  • 《马尼拉》桌游期望计算器
  • 240422 leetcode exercises
  • 2025高频面试算法总结篇【其他】
  • ADB->查看某个应用的版本信息
  • 性能比拼: Nginx vs Apache
  • vdso内核与glibc配合的相关逻辑分析
  • IDEA打不开、打开报错
  • 【Easylive】手动实现分布式事务解决方案流程解析
  • KZ队史首冠,透过春决看CF电竞张扬的生命力
  • “小时光:地铁里的阅读”摄影展开幕,嘉宾共话日常生活与阅读
  • 上海农房翻建为何难?基层盼政策适度松动
  • 30小时已过,俄罗斯复活节停火不再延长
  • 2025中国互联网企业家座谈会在京召开
  • 美国多地举行抗议活动,特朗普经济政策支持率创新低