2026/2/12 6:01:52
网站建设
项目流程
高碑店网站网站建设,网站 搜索 关键字 description,wordpress 添加表格,万州网站建设公司【Linux】零基础学习命名管道与共享内存 #xff08;2025–2026 年仍然最实用的两种经典进程间通信方式#xff09;
命名管道#xff08;FIFO#xff09;和共享内存#xff08;Shared Memory#xff09;是 Linux 中最基础、最常用的两种 IPC#xff08;进程间通信…【Linux】零基础学习命名管道与共享内存2025–2026 年仍然最实用的两种经典进程间通信方式命名管道FIFO和共享内存Shared Memory是 Linux 中最基础、最常用的两种IPC进程间通信方式但它们的适用场景、性能、复杂度、使用难度差异非常大。下面用最直白的语言 对比 代码 常见误区的方式帮你快速建立认知。一、先看对比表强烈建议先背熟这张表维度命名管道FIFO / mkfifo共享内存shmget / shm_open谁更常用2025–2026 视角是否需要亲缘关系不需要不需要—数据是否需要拷贝需要内核 → 用户 → 内核不需要直接映射到进程地址空间共享内存完胜传输方向单向默认或双向开两个管道双向同一块内存谁都能读写共享内存更灵活是否有阻塞有默认读写都会阻塞无除非自己加信号量/互斥锁命名管道更“省心”最大数据量通常 64KB 缓冲区可调理论上很大受物理内存限制共享内存容量更大性能中等系统调用 拷贝极高几乎只有内存访问共享内存碾压编程复杂度低像普通文件读写高需要自己做同步、清理命名管道对新手友好典型场景简单日志传递、脚本间通信、父子进程高性能、大数据量、实时计算、数据库—是否跨机器否同一台机器否同一台机器—一句话总结选择依据要简单、数据量小、不在意性能→ 用命名管道追求极致性能、数据量大、频繁读写→ 用共享内存但要自己管同步二、命名管道FIFO——最容易上手的 IPC创建方式两种# 方法1命令行创建最常用mkfifomyfifo# 方法2C语言创建mkfifo(myfifo, 0666);最经典的父子进程通信示例// pipe_writer.c#includestdio.h#includefcntl.h#includeunistd.hintmain(){intfdopen(myfifo,O_WRONLY);// 只写方式打开if(fd-1){perror(open);return1;}char*msgHello from writer!\n;write(fd,msg,strlen(msg));close(fd);return0;}// pipe_reader.c#includestdio.h#includefcntl.h#includeunistd.hintmain(){intfdopen(myfifo,O_RDONLY);// 只读方式打开if(fd-1){perror(open);return1;}charbuf[1024]{0};ssize_tnread(fd,buf,sizeof(buf));printf(Received: %s,buf);close(fd);return0;}关键行为读端先打开 → 阻塞直到有写端打开写端先打开 → 阻塞直到有读端打开所有写端关闭后读端 read() 返回 0EOF管道缓冲区满时写端阻塞Shell 中最常见的用法非常实用mkfifo/tmp/mypipe# 终端1生产者echodata from terminal 1/tmp/mypipe# 终端2消费者cat/tmp/mypipe三、共享内存——性能之王但最容易出错两种主流方式2025 年仍在并存方式API优点缺点推荐场景System V 共享内存shmget / shmat / shmdt历史悠久几乎所有系统支持API 古老key 管理麻烦传统应用、老项目POSIX 共享内存shm_open / mmap接口更现代与文件类似需要手动 unlink新项目、推荐优先使用POSIX 共享内存最简示例强烈推荐写法writer.c#includestdio.h#includefcntl.h#includesys/mman.h#includeunistd.h#defineSHM_NAME/my_shared_mem#defineSHM_SIZE4096intmain(){intfdshm_open(SHM_NAME,O_CREAT|O_RDWR,0666);if(fd-1){perror(shm_open);return1;}ftruncate(fd,SHM_SIZE);char*ptrmmap(0,SHM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if(ptrMAP_FAILED){perror(mmap);return1;}sprintf(ptr,Hello from writer process! PID%d,getpid());printf(Data written. Press Enter to exit...\n);getchar();munmap(ptr,SHM_SIZE);close(fd);shm_unlink(SHM_NAME);// 清理重要return0;}reader.c#includestdio.h#includefcntl.h#includesys/mman.h#includeunistd.h#defineSHM_NAME/my_shared_mem#defineSHM_SIZE4096intmain(){intfdshm_open(SHM_NAME,O_RDONLY,0666);if(fd-1){perror(shm_open);return1;}char*ptrmmap(0,SHM_SIZE,PROT_READ,MAP_SHARED,fd,0);if(ptrMAP_FAILED){perror(mmap);return1;}printf(Read from shared memory: %s\n,ptr);munmap(ptr,SHM_SIZE);close(fd);return0;}四、零基础最容易踩的 8 个大坑强烈建议收藏命名管道忘记创建 FIFO直接 open 会失败一端关闭后另一端行为没预期读到 EOF多个写端并发写 → 数据可能交错无原子性共享内存忘记同步读写冲突 → 数据错乱 / 撕裂忘记 shm_unlink → 重启程序后 shm_open 可能失败mmap 失败后没检查 MAP_FAILED进程崩溃后共享内存没释放用 ipcs -m 查看残留System V 与 POSIX 混用导致 key 冲突五、快速总结一句话口诀想简单、数据少、顺序读写→ 命名管道像文件一样用要速度、数据大、频繁交互→ 共享内存但必须自己加锁/信号量你现在最想搞清楚哪一部分命名管道的阻塞行为细节如何在共享内存上加互斥锁/信号量System V 共享内存的写法对比实际项目中怎么选比如日志系统、实时数据处理想看一个带同步的完整共享内存例子告诉我你的具体困惑点我可以继续展开。