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;
}
结果:
使用套接字实现了服务器和客户端间的通信。
优缺点:
| 优点 | 缺点 | 应用场景 |
|---|---|---|
| 支持跨主机通信,数据传输灵活。 | 编程较为复杂,需要理解网络协议。 | 远程进程间通信或分布式系统。 |
总结
| 通信方式 | 优点 | 缺点 | 应用场景 |
|---|---|---|---|
| 管道 | 简单易用,适合父子进程通信。 | 只能单向通信,无法跨进程。 | 父子进程间数据传输。 |
| 消息队列 | 支持异步通信,消息排队。 | 阻塞问题,消息队列容量有限。 | 高并发的异步通信。 |
| 共享内存 | 高效,速度快。 | 需要同步机制。 | 高效数据交换。 |
| 信号 | 简单易用,适合事件通知。 | 只能传递简单信息。 | 异步事件通知。 |
| 套接字 | 支持跨主机通信,灵活多变。 | 编程复杂,需理解网络协议。 | 分布式系统,远程进程通信。 |
这些通信方式在实际开发中都有着广泛的应用,选择合适的通信方式可以有效提高系统的性能和可维护性。
相关文章:
Linux 进程与线程间通信方式及应用分析
Linux 进程与线程间通信方式及应用分析 文章目录 Linux 进程与线程间通信方式及应用分析 1. 管道(Pipe)1.1 匿名管道(Anonymous Pipe)示例代码:结果: 1.2 命名管道(FIFO)示例代码&am…...
AI日报 - 2024年04月22日
🌟 今日概览(60秒速览) ▎🤖 模型进展 | Google发布Gemini 2.5 Flash,强调低延迟与成本效益;Kling AI 2.0展示多轴运动视频生成;研究揭示SLM在知识图谱上优于LLM,RLHF在推理提升上存局限。 ▎💼…...
FreeRTos学习记录--2.内存管理
后续的章节涉及这些内核对象:task、queue、semaphores和event group等。为了让FreeRTOS更容易使用,这些内核对象一般都是动态分配:用到时分配,不使用时释放。使用内存的动态管理功能,简化了程序设计:不再需…...
HAL库(STM32CubeMX)——高级ADC学习、HRTIM(STM32G474RBT6)
系列文章目录 文章目录 系列文章目录前言存在的问题HRTIMcubemx配置前言 对cubemx的ADC的设置进行补充 ADCs_Common_Settings Mode:ADC 模式 Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选 ADC_Se…...
单例模式(线程安全)
1.什么是单例模式 单例模式(Singleton Pattern)是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单…...
FreeRTos学习记录--1.工程创建与源码概述
1.工程创建与源码概述 1.1 工程创建 使用STM32CubeMX,可以手工添加任务、队列、信号量、互斥锁、定时器等等。但是本课程不想严重依赖STM32CubeMX,所以不会使用STM32CubeMX来添加这些对象,而是手写代码来使用这些对象。 使用STM32CubeMX时&…...
基于大模型的血栓性外痔全流程风险预测与治疗管理研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究意义 二、血栓性外痔概述 2.1 定义与发病机制 2.2 临床表现与诊断方法 2.3 现有治疗手段综述 三、大模型在血栓性外痔预测中的应用原理 3.1 大模型技术简介 3.2 模型构建与训练数据来源 3.3 模型预测血栓性外痔的工作流程…...
进程控制(linux+C/C++)
目录 进程创建 写时拷贝 fork 进程终止 退出码 进程退出三种情况对应退出信号 :退出码: 进程退出方法 进程等待 两种方式 阻塞等待和非阻塞等待 小知识 进程创建 1.在未创建子进程时,父进程页表对于数据权限为读写,对于…...
C++如何处理多线程环境下的异常?如何确保资源在异常情况下也能正确释放
多线程编程的基本概念与挑战 多线程编程的核心思想是将程序的执行划分为多个并行运行的线程,每个线程可以独立处理任务,从而充分利用多核处理器的性能优势。在C中,开发者可以通过std::thread创建线程,并使用同步原语如std::mutex、…...
TensorBoard如何在同一图表中绘制多个线条
1. 使用不同的日志目录 TensorBoard 会根据日志文件所在的目录来区分不同的运行。可以为每次运行指定一个独立的日志目录,TensorBoard 会自动将这些目录中的数据加载并显示为不同的运行。 示例(TensorFlow): import tensorflow…...
微软Entra新安全功能引发大规模账户锁定事件
误报触发大规模锁定 多家机构的Windows管理员报告称,微软Entra ID新推出的"MACE"(泄露凭证检测应用)功能在部署过程中产生大量误报,导致用户账户被大规模锁定。这些警报和锁定始于昨夜,部分管理员认为属于误…...
基于FPGA的一维时间序列idct变换verilog实现,包含testbench和matlab辅助验证程序
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 DCT离散余弦变换 4.2 IDCT逆离散余弦变换 4.3 树结构实现1024点IDCT的原理 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) matlab仿真结果 FPGA仿真结果 由于FP…...
Linux进程5-进程通信常见的几种方式、信号概述及分类、kill函数及命令、语法介绍
目录 1.进程间通信概述 1.1进程通信的主要方式 1.2进程通信的核心对比 2.信号 2.1 信号的概述 2.1.1 信号的概念 2.2信号的核心特性 2.3信号的产生来源 2.4信号的处理流程 2.5关键系统调用与函数 2.6常见信号的分类及说明 2.6.1. 标准信号(Standard Sig…...
[架构之美]一键服务管理大师:Ubuntu智能服务停止与清理脚本深度解析
[架构之美]一键服务管理大师:Ubuntu智能服务停止与清理脚本深度解析 服务展示: 运行脚本: 剩余服务: 一、脚本设计背景与核心价值 在Linux服务器运维中,服务管理是日常操作的重要环节。本文介绍的智能服务管理脚本&a…...
C++算法(10):二叉树的高度与深度,(C++代码实战)
引言 在二叉树的相关算法中,高度(Height)和深度(Depth)是两个容易混淆的概念。本文通过示例和代码实现,帮助读者清晰区分二者的区别。 定义与区别 属性定义计算方式深度从根节点到该节点的边数根节点深度…...
k8s 基础入门篇之开启 firewalld
前面在部署k8s时,都是直接关闭的防火墙。由于生产环境需要开启防火墙,只能放行一些特定的端口, 简单记录一下过程。 1. firewall 与 iptables 的关系 1.1 防火墙(Firewall) 定义: 防火墙是网络安全系统&…...
Psychology 101 期末测验(附答案)
欢呼 啦啦啦~啦啦啦~♪(^∇^*) 终于考过啦~ 开心(*^▽^*) 撒花✿✿ヽ(▽)ノ✿ |必须晒下证书: 判卷 记录下判卷,还是错了几道,填空题2道压根填不上。惭愧~ 答案我隐藏了,实在想不出答案的朋友可以留言,不定时回复。 建议还是认认真真的学习~认认真真的考试~,知识就…...
安全协议分析概述
一、概念 安全协议(security protocol),又称密码协议。是以密码学为基础的消息交换协议,在网络中提供各种安全服务。(为解决网络中的现实问题、满足安全需求) 1.1 一些名词 那什么是协议呢? …...
基础学习:(7)nanoGPT 剩下的细节
文章目录 前言3 继续巴拉结构3.1 encode 和 embedding3.2 全局layernorm3.3 lm_head(language modeling) 和 softmax3.4 softmax 和 linear 之间的 temperature和topk3.5 weight tying 前言 在 基础学习:(6)中, 在运行和训练代码基础上,向代…...
【HDFS】verifyEC命令校验EC数据正确性
verifyEC命令是HDFS里用于验证EC文件正确性的一个工具。这是一个非常实用的工具,能帮助我们确定EC的数据内容是否正确,并且如果不正确的话,还有可能会触发reportBadBlock给NN,让NN进行块的重构。 本文先介绍一下verifyEC命令的使用方法,再描述其实现原理细节。 一、命令…...
YOLO11改进,尺度动态损失函数Scale-based Dynamic Loss,减少标签不准确对损失函数稳定性的影响
在目标检测领域,标签噪声与尺度敏感问题始终是制约模型性能提升的"阿喀琉斯之踵"。2025年CVPR最佳论文提出的尺度动态损失函数(Scale-based Dynamic Loss, SDL),通过构建自适应损失调节机制,不仅实现了对YOLOv11检测精度的指数级提升,更重新定义了损失函数的设…...
Spark-SQL连接Hive总结及实验
一、核心模式与配置要点 1. 内嵌Hive 无需额外配置,直接使用,但生产环境中几乎不使用。 2. 外部Hive(spark-shell连接) 配置文件:将hive-site.xml(修改数据库连接为node01)、core-site.xml、…...
ROS 2的跨平台优势:国产芯片与Ubuntu系统的深度协同
一、国产硬件全场景适配:从教育到工业的ROS 2革命 瑞芯微三剑客性能解析 芯片架构特性ROS 2优化方案典型延迟/算力RK3399双核A72四核A53启用rmw_fastrtps内存池隔离通信延迟≤1.5msRK3588四核A766TOPS NPUrknn_ros2中间件实现算法热加载目标检测15ms4KRK3576六核A…...
Linux Wlan-四次握手(eapol)框架流程
协议基础 基于 IEEE 802.1X 标准实现的协议 抓包基础 使用上一章文章的TPLINK wn722n v1网卡在2.4G 频段抓包(v2、v3是不支持混杂模式的) eapol的四个交互流程 根据不同的认证模式不同,两者的Auth流程有所不同,但是握手流程基…...
web组件和http协议
1.web组件 2.自定义元素 3.影子DOM 4.HTML模板 5.http协议 6.tcp ip协议...
软件工程师中级考试-上午知识点总结(下)
6. 知识产权和标准化 软件著作权客体:指的是受软件著作权保护的对象,即计算机程序和相关文档。知识产权具有严格的地域性。不受保护期限制:著名权、修改权、保护作品完整权;注意的是,发表权受保护期限制。专利权在期满…...
IO流--字节流详解
IO流 用于读写数据的(可以读写文件,或网络中的数据) 概述: I指 Input,称为输入流:负责从磁盘或网络上将数据读到内存中去 O指Output,称为输出流,负责写数据出去到网络或磁盘上 因…...
Cesium学习笔记——dem/tif地形的分块与加载
前言 在Cesium的学习中,学会读文档十分重要!!!在这里附上Cesium中英文文档1.117。 在Cesium项目中,在平坦坦地球中加入三维地形不仅可以增强真实感与可视化效果,还可以提升用户体验与交互性,…...
FPGA 中 XSA、BIT 和 DCP 文件的区别
在 FPGA(现场可编程门阵列)开发中,XSA、BIT 和 DCP 文件是常见的文件类型,它们在功能、用途、文件内容等方面存在明显区别,以下是详细介绍: 1. XSA 文件 定义与功能 XSA(Xilinx Shell Archiv…...
Vmware esxi 给现有磁盘增加空间后并扩展系统里磁盘空间
当前EXSI上虚拟机所在的单独数据磁盘空间满了,需要对空间进行扩容,我们先在主机对磁盘容量进行调整,然后在系统里面对磁盘空间进行拓展,这些操作需要保留数据并且不改变现有的磁盘格局。 遵循大致操作流程是: 1.先登录…...
