Linux 进程间通信(IPC)详解 1. 进程间通信的方法进程间通信IPCInter-Process Communication是操作系统中不同进程之间交换数据与信息的机制。Linux 下常用的进程间通信方式包括管道包括无名管道和有名管道用于有亲缘关系或任意进程之间的字节流传输。信号内核与应用层之间的一种异步通信机制用于通知进程发生了某种事件。消息队列以消息为单位进行数据交换支持按类型读取。共享内存多个进程直接映射同一块物理内存读写效率最高。信号灯信号量用于进程间的同步与互斥控制对共享资源的访问。2. 管道2.1 无名管道无名管道只能用于具有亲缘关系的进程间通信例如父子进程之间。它由内核提供一段缓冲区通过文件描述符进行读写。函数接口pipeint pipe(int pipefd[2]); 功能创建一段用于进程间通信的内核缓存区 参数pipefd[0]读文件描述符 pipefd[1]写文件描述符 返回值成功返回 0失败返回 -12.2 管道特性管道中有写端管道中有数据直接读出。管道中没有数据阻塞等待直到数据写入后再读出。管道中没有写端管道中有数据直接读出。管道中没有数据直接结束不需要阻塞等待。管道中有读端管道没有写满64K直接写入数据。管道写满需要等数据读出后才能继续写入。管道中没有读端写入数据会产生管道破裂的错误使进程直接退出。2.3 有名管道有名管道可以用于任意两个进程之间的通信。读写两端必须同时加入才能继续向下执行如果只有读写一端则会阻塞等待直到另一端加入。函数接口mkfifoint mkfifo(const char *pathname, mode_t mode); 功能创建一个有名管道 参数pathname有名管道的路径 mode权限 返回值成功返回 0失败返回 -1编程练习实现 read.c 和 write.c 聊天功能编写两个程序 read.c 和 write.cwrite.c 负责从终端接收内容发送给 read.c。read.c 将接收内容打印后再从终端接收内容发送给 write.c。write.c 打印后重复执行如上内容实现 read.c 和 write.c 的聊天功能。3. 信号3.1 信号概述信号是内核层与应用层通信的一种机制。应用层收到信号后的处理方式有三种缺省按照默认方式处理信号。忽略不处理信号。捕捉按照指定的方式处理信号。3.2 常见信号种类信号触发方式说明SIGINT从键盘输入 ctrl c中断信号SIGQUIT从键盘输入 ctrl \退出信号SIGKILLkill -9不能被忽略和捕捉SIGSEGV非法内存访问段错误SIGPIPE管道破裂写无读端管道时触发SIGALRM定时时间达到由 alarm 触发SIGCHLD子进程结束通知父进程回收SIGCONT继续执行恢复暂停进程SIGSTOP暂停信号不能被忽略和捕捉SIGTSTP从键盘输入 ctrl z挂起信号SIGIO异步 IO异步 IO 信号注意9 号SIGKILL和 19 号SIGSTOP信号不能被忽略和捕捉。3.3 函数接口signaltypedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 功能改变信号的处理方式 参数signum信号的编号 handler SIG_IGN忽略信号 SIG_DFL缺省默认方式处理信号 捕捉传入信号的处理方式 返回值成功返回上一次注册的信号对应的处理方式失败返回 SIG_ERRpauseint pause(void); 功能让进程睡眠alarmunsigned int alarm(unsigned int seconds); 功能隔 seconds 秒后给调用进程发送 SIGALRM 信号3.4 信号编号速查表1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN1 36) SIGRTMIN2 37) SIGRTMIN3 38) SIGRTMIN4 39) SIGRTMIN5 40) SIGRTMIN6 41) SIGRTMIN7 42) SIGRTMIN8 43) SIGRTMIN9 44) SIGRTMIN10 45) SIGRTMIN11 46) SIGRTMIN12 47) SIGRTMIN13 48) SIGRTMIN14 49) SIGRTMIN15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX4. 信号量信号灯信号量用于进程间的同步与互斥通过资源计数控制对共享资源的访问。int sem_post(sem_t *sem); 功能释放资源让资源数 1 参数sem信号量空间首地址 返回值成功返回 0失败返回 -15. 消息队列5.1 IPC 对象IPC 对象是内核中的一种内存文件每个 IPC 对象可以创建一个消息队列、一个共享内存和一个信号灯。5.2 IPC 对象查看命令ipcs -q/m/s ipcrm -Q/M/S IPC对象名称(Key值) ipcrm -q/m/s 消息队列ID号/共享内存ID号/信号量数组ID号5.3 消息队列操作方式创建 IPC 对象的名称ftok创建消息队列msgget消息队列发送消息msgsnd消息队列接收消息msgrcv消息队列控制msgctl5.4 函数接口ftokkey_t ftok(const char *pathname, int proj_id); 功能根据目录名和 8 位项目 ID 生成 key 值 参数pathname目录名 proj_id项目 ID 返回值成功返回 key_t 类型的 IPC 对象名称失败返回 -1msggetint msgget(key_t key, int msgflg); 功能根据 key 值创建消息队列 参数keyIPC 对象名称 msgflgIPC_CREAT 不存在创建IPC_EXCL 存在报错 返回值成功返回消息队列 ID失败返回 -1msgsndint msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 功能向消息队列中发送消息 参数msqid消息队列 ID 号 msgp发送消息的空间的首地址 msgsz发送消息内容的大小 msgflg消息属性默认 0 返回值成功返回 0失败返回 -1msgrcvssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); 功能从消息队列中接收消息 参数msqid消息队列的 ID 号 msgp存放消息空间的首地址 msgsz最多接收数据的字节数 msgtyp接收消息的 ID 号 msgflg默认为 0 返回值成功返回实际接收字节数失败返回 -1msgctlint msgctl(int msqid, int cmd, struct msqid_ds *buf); 功能向消息队列发送命令 参数msqid消息队列 ID 号 cmdIPC_STAT 获得消息队列状态信息 IPC_SET 修改消息队列权限 IPC_RMID 删除消息队列 返回值成功返回 0失败返回 -15.5 编程练习实现 send.c 和 recv.c编写 send.c 和 recv.csend.c 负责从终端接收字符串发送到消息队列。recv.c 负责从消息队列接收内容并打印在终端。6. 共享内存6.1 共享内存概述共享内存是进程间通信最高效的形式。6.2 共享内存操作步骤创建 IPC 对象名称键值ftok创建共享内存shmget将进程地址映射到共享内存中shmat使用共享内存空间解除映射shmdt销毁共享内存空间shmctl6.3 函数接口shmgetint shmget(key_t key, size_t size, int shmflg); 功能创建一个共享内存 参数keyIPC 对象名称 size共享内存的大小 shmflgIPC_CREAT 不存在就创建IPC_EXCL 存在就报错 返回值成功返回共享内存 ID失败返回 -1shmatvoid *shmat(int shmid, const void *shmaddr, int shmflg); 功能将进程空间地址映射到共享内存中 参数shmid共享内存 ID 号 shmaddrNULL 选择默认的合适地址映射 shmflg0 返回值成功返回映射到共享空间中的地址失败返回 -1shmdtint shmdt(const void *shmaddr); 功能解除映射 参数shmaddr映射到共享内存空间的首地址 返回值成功返回 0失败返回 -1shmctlint shmctl(int shmid, int cmd, struct shmid_ds *buf); 功能向共享内存发送命令 参数shmid共享内存 ID 号 cmdIPC_STAT 获得属性 IPC_SET 设置权限 IPC_RMID 删除共享内存 返回值成功返回 0失败返回 -17. 有名信号量7.1 函数接口semgetint semget(key_t key, int nsems, int semflg); 功能创建信号量数组 参数keyIPC 对象名称 nsems信号量的个数 semflgIPC_CREAT 不存在创建IPC_EXCL 存在报错 返回值成功返回信号量数组的 ID 号失败返回 -1semctlint semctl(int semid, int semnum, int cmd, ...); 功能对信号量数组进行控制操作 参数semid信号量数组 ID 号 semnum信号量编号 cmdIPC_STAT 获得属性 IPC_SET 设置权限 IPC_RMID 删除信号量数组 返回值成功返回 0失败返回 -1semopint semop(int semid, struct sembuf *sops, size_t nsops); 功能对信号量进行 P/V 操作 参数semid信号量数组 ID 号 sops操作结构体数组 nsops操作个数 返回值成功返回 0失败返回 -1

相关新闻

最新新闻

STM32F407驱动AD9954实现高精度DDS信号发生器

STM32F407驱动AD9954实现高精度DDS信号发生器

简介:一套面向STM32F407与AD9954芯片的DDS信号发生器完整工程源码包,为需要高精度、宽频带(最高500 MHz输出)且支持快速跳频的信号源开发场景,提供可直接运行的Keil MDK项目。工程已集成AD9954初始化、频率/相位寄存器…

2026/9/1 7:01:35
432道MySQL面试题 381 - 400 题

432道MySQL面试题 381 - 400 题

为方便阅读,这里整理了整个系列的索引导航。本系列共 432 道 MySQL 面试题,按每 20 题为一篇进行连载,点击下方链接即可跳转到对应章节,方便你按需查阅、系统复习。 432道MySQL面试题 1 - 20 题 432道MySQL面试题 21 - 40 题 432道MySQL面试题 41 - 60 题 432道MySQL面试题…

2026/9/1 7:01:35
Qt上位机开发:嵌入式数据存储与SQLite应用实践

Qt上位机开发:嵌入式数据存储与SQLite应用实践

在嵌入式设备的联调、测试、产线和售后阶段,上位机几乎是一个绕不开的工程角色。很多嵌入式项目并不需要复杂的云端平台,而是需要一台运行在 Windows 或 Linux 上的 PC 软件,通过串口、USB、TCP/UDP 与下位机通信,完成参数下发、状…

2026/9/1 7:01:35
科技服务机构如何构建系统性个性化创新服务方案?

科技服务机构如何构建系统性个性化创新服务方案?

观点作者:科易网-国家科技成果转化(厦门)示范基地 近年来,全球科技竞争愈演愈烈,科技创新已成为驱动国家竞争力、产业转型升级和经济社会高质量发展的核心引擎。与此同时,科技成果转化作为科技成果价值实现…

2026/9/1 7:01:35
Rust 数组与元组:从固定长度数据类型到安全内存实践

Rust 数组与元组:从固定长度数据类型到安全内存实践

1. 背景与核心概念很多初学 Rust 的朋友,在看完变量、函数、所有权之后,会进入一个比较尴尬的阶段:想写点小项目练手,却发现连“怎么存一组数据”都要纠结半天。是应该用数组,还是用元组,还是直接用标准库里…

2026/9/1 7:01:35
四、STL 容器与数据结构(进阶)(一)

四、STL 容器与数据结构(进阶)(一)

四、STL 容器与数据结构()一句话总览:STL 容器的选择本质上是在“连续内存、节点结构、有序性、哈希查找、插入删除效率、缓存友好性”之间做权衡;vector 是默认首选,map/set 适合有序和范围查询,unordered…

2026/9/1 6:56:34