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

linux当中的六大进程间通信方式

IPC-InterProcess Communication

管道 (Pipe)

传输无格式的字节流
半双工

匿名管道 (Anonymous Pipe)

只存在在内存当中
父子等亲缘进程间的单向数据
生存周期:随着亲缘进程的退出而消失

在shell当中的 | 就是创建了匿名管道

命名管道 (Named Pipe / FIFO)

是一种文件,存储在文件系统当中
任何进程之间都可以使用有名管道进行通信
生命周期:一直存在在文件系统当中,主动删除才会消失

// 程序当中创建fifomkfifo(管道文件路径,权限位);
# shell当中创建fifomkfifo管道名

信号 (Signal)

软中断
本质:进程信息结构体中的int类型的信号位
一种异步通知机制,用于通知进程发生了某种事件,传递信息量小,主要用于异常处理或进程控制,而非大批量数据交换。

不可靠信号(1-31)

信号名称编号默认动作说明(常见触发原因)
SIGHUP1终止(Term)挂断信号,通常由控制终端挂起或控制进程退出时发出。
SIGINT2终止(Term)来自键盘的中断信号,通常通过Ctrl+C触发。
SIGQUIT3终止并转储核心(Core)来自键盘的退出信号,通常通过Ctrl+\触发,会生成core dump文件。
SIGILL4终止并转储核心(Core)进程执行了非法指令。
SIGTRAP5终止并转储核心(Core)跟踪或断点陷阱,常用于调试器。
SIGABRT6终止并转储核心(Core)进程调用abort()函数时发出的异常终止信号。
SIGIOT6终止并转储核心(Core)IOT陷阱,与SIGABRT是等价的。
SIGBUS7终止并转储核心(Core)总线错误,通常由不正确的内存访问导致。
SIGFPE8终止并转储核心(Core)浮点运算异常(如除零错误)。
SIGKILL9终止(Term)强制杀死进程。此信号不可被捕获、阻塞或忽略。
SIGUSR110终止(Term)用户自定义信号1,可由应用程序自行定义用途。
SIGSEGV11终止并转储核心(Core)段错误,进程试图访问非法内存地址。
SIGUSR212终止(Term)用户自定义信号2,可由应用程序自行定义用途。
SIGPIPE13终止(Term)管道破裂。进程向一个没有读端的管道(或socket)写入数据。
SIGALRM14终止(Term)alarm()setitimer()函数设置的定时器超时。
SIGTERM15终止(Term)终止信号,是kill命令的默认信号,允许进程进行清理后退出。
SIGSTKFLT16终止(Term)协处理器栈错误,该信号在现代Linux中已很少使用。
SIGCHLD17忽略(Ign)子进程状态发生变化(如停止或终止)时,向父进程发送此信号。
SIGCONT18继续(Cont)让一个被暂停的进程继续运行。
SIGSTOP19停止进程(Stop)暂停进程。此信号不可被捕获、阻塞或忽略。
SIGTSTP20停止进程(Stop)来自终端的停止信号,通常通过Ctrl+Z触发。
SIGTTIN21停止进程(Stop)后台进程尝试从控制终端读取数据时发送。
SIGTTOU22停止进程(Stop)后台进程尝试向控制终端写入数据时发送。
SIGURG23忽略(Ign)套接字上出现紧急数据或带外数据。
SIGXCPU24终止并转储核心(Core)进程的CPU使用时间超过了其资源限制(setrlimit)。
SIGXFSZ25终止并转储核心(Core)进程创建的文件大小超过了其资源限制(setrlimit)。
SIGVTALRM26终止(Term)虚拟定时器(setitimer)超时,只计算进程用户态CPU时间。
SIGPROF27终止(Term)系统资源定时器(setitimer)超时,统计进程用户和内核态CPU时间。
SIGWINCH28忽略(Ign)终端窗口大小发生改变。
SIGIO/SIGPOLL29终止(Term)文件描述符上可以进行I/O操作(异步I/O通知)。
SIGPWR30终止(Term)电源故障或重启信号(System V系统)。
SIGSYS31终止并转储核心(Core)进程调用了错误的系统调用参数。

套接字 (Socket)

Unix域套接字 (Unix Domain Socket) 最初由BSD开发,是最通用的IPC机制,支持不同计算机间的网络通信。其本地通信模式(Unix域套接字)也常用于单机内高效的双向通信。

TCP/UDP—ROS1

DDS—ROS2

消息队列(Message Queue)

在kernel当中的位置ipc/msg.c
数据结构:链表

//System V#include<sys/msg.h>// 创建---message getintmsgget(key_tkey,intmsgflg);key:队列的键值ftok()生成 IPC_PRIVATE msgflg:权限和标志 IPC_CREAT创建 IPC_EXCL防止重复创建 权限位(eg:0666)返回值:成功返回消息队列ID(msqid),失败返回-1// 发送方---message sendintmsgsnd(intmsqid,constvoid*msgp,size_tmsgsz,intmsgflg);msqid:msgget()返回的队列ID。 msgp:指向消息结构体(自定义)。 msgsz:消息数据部分大小。 msgflg:0:阻塞 IPC_NOWAIT:非阻塞,队列满则返回错误 返回值:成功返回0,失败返回-1// 接收方---message receivessize_tmsgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsgflg);msqid:msgget()返回的队列ID。 msgp:指向消息结构体(自定义,需要与发送者一样)。 msgsz:消息数据部分大小。 msgtyp:按类型读取的关键参数。0取队头消息,无论类型>0取该类型第一条<0取绝对值小于等于它的最小类型消息 msgflg:0:阻塞接收消息 IPC_NOTWAIT:消息队列为空时返回错误 MSG_EXCEPT:返回队列当中第一个不为msgtype的消息 返回值:成功返回实际读取的数据字节数,失败返回-1// 控制(包含删除)---message controlintmsgctl(intmsqid,intcmd,structmsqid_ds*buf);cmd:控制命令。 IPC_RMID用于删除队列。 IPC_STAT获取队列属性。 IPC_SET设置队列属性。 buf:用于存储或设置队列属性的结构体指针。 返回值:成功返回0,失败返回-1

共享内存(Shared Memory)

实现方式:多个进程的虚拟内存映射到同一块物理内存区域
通信速度最快

#include// 获取键值(key_t)--- file tokenkey_tftok(constchar*pathname,intproj_id);pathname:必须是一个已存在且可以访问的文件路径 proj_id:项目标识符。它可以用来区分同一个文件生成的多个不同的键值 返回值:键值(key_t),失败返回-1// 创建---shared memory getintshmget(key_tkey,size_tsize,intshmflg);key:键值 size:共享内存大小(字节),建议为页大小(4096)的整数倍 shmflg:创建方式 IPC_CREAT:不存在则创建,存在则返回标识符 IPC_EXCL:如果存在则返回错误0666:权限 返回值:共享内存标识符---句柄(shmid),失败返回-1// 挂载---shared memory attachvoid*shmat(intshmid,constvoid*shmaddr,intshmflg);shmid:共享内存标识符 shmaddr:通常设为NULL,由系统自动选择地址 shmflg:共享内存读写权限0:可读写 SHM_RDONLY:只读 返回值:共享内存起始地址指针,失败返回(void*)-1// 分离---shared memory detachintshmdt(constvoid*shmaddr);shmaddr:要断开的内存的地址 返回值:成功返回0,失败返回-1// 控制(包括删除)---shared memory controlintshmctl(intshmid,intcmd,structshmid_ds*buf);shmid:共享内存标识符 cmd:控制命令 IPC_RMID删除 IPC_STAT获取状态 IPC_SET设置共享内存状态信息 buf:保存状态信息的数据结构 返回值:成功返回0,失败返回-1

ROS2当中的零拷贝,就是共享内存

信号量(Semaphore)

  • 二值信号量
  • 计数信号量
// 创建---semaphore getintsemget(key_tkey,intnsems,intsemflg);key:信号量标识,**不同进程可以使用同一个信号量**nsems:信号量集中信号量的个数 semflg:信号量集的访问权限 IPC_CREAT|0666返回值:信号量标识符---句柄(semid),失败返回-1// 控制信号量集---semaphore controlintsemctl(intsemid,intsemnum,intcmd,...);semid:信号量标识符 semnum:信号量在集中的索引 cmd:控制命令 SETVAL:设置值 IPC_STAT:获取信号量集的状态信息。 IPC_RMID:删除信号量集。 GETVAL:获取信号量的当前值, GETPID:获取最后一个对信号量执行wait操作的进程的PID。 GETNCNT:获取等待信号量值大于0的进程数。 GETZCNT:获取等待信号量值等于0的进程数。..:可选参数,其类型和含义取决于cmd参数的值。 返回值:取决于cmd,失败返回-1// 使用(P/V操作)---semaphore operationintsemop(intsemid,structsembuf*sops,unsignednsops);semid:信号量标识符 sops:操作数组 包含 sem_num(信号量索引)、sem_op(操作值)、sem_flg(标志)// nsops:操作数组的元素个数// 返回值:成功返回0,失败返回 -1structsembuf{unsignedshortsem_num;// 信号量索引shortsem_op;// 操作值shortsem_fig;// 标志}

System V IPC
这是AT&T贝尔实验室发展的一套经典IPC机制,适用于单机内部通信。共享内存是最快的IPC方式,而信号量则常作为同步工具配合使用。
POSIX IPC
为提升System V IPC的可移植性和灵活性而设计的标准化接口。它提供了更现代化的API,并且新增了线程同步原语(如互斥量、条件变量)。


POSIX消息队列 (mqueue.h)

POSIX 消息队列相比 System V 消息队列,提供了基于优先级的消息传递、异步通知机制(信号或线程)、以及更简洁的文件描述符式 API。编译时需链接-lrt

// 打开/创建消息队列mqd_tmq_open(constchar*name,intoflag,.../* mode_t mode, struct mq_attr *attr */);name:消息队列名称,必须以斜杠开头(如"/myqueue"),且不含其他斜杠 oflag:访问标志 O_RDONLY:只读 O_WRONLY:只写 O_RDWR:读写 O_CREAT:不存在则创建(需提供 mode 和 attr 参数) O_EXCL:与 O_CREAT 连用,队列已存在则失败 O_NONBLOCK:非阻塞模式 mode:创建权限(如0666),仅在 O_CREAT 时使用 attr:队列属性,NULL表示使用系统默认值structmq_attr{longmq_flags;// 队列标志,0 或 O_NONBLOCKlongmq_maxmsg;// 队列最大消息数longmq_msgsize;// 单条消息最大字节数longmq_curmsgs;// 当前队列中消息数(只读)};返回值:成功返回消息队列描述符(mqd_t),失败返回(mqd_t)-1并设置 errno// 发送消息intmq_send(mqd_tmqdes,constchar*msg_ptr,size_tmsg_len,unsignedintmsg_prio);mqdes:mq_open()返回的队列描述符 msg_ptr:指向消息数据的指针 msg_len:消息长度(字节数),不能超过 mq_msgsize msg_prio:消息优先级,值越大优先级越高,队列按优先级从高到低排序 返回值:成功返回0,失败返回-1并设置 errno 说明:若队列满且未设置 O_NONBLOCK,调用线程将阻塞// 带超时发送消息intmq_timedsend(mqd_tmqdes,constchar*msg_ptr,size_tmsg_len,unsignedintmsg_prio,conststructtimespec*abs_timeout);abs_timeout:绝对超时时间(基于 CLOCK_REALTIME) 返回值:成功返回0,超时返回-1且 errno 为 ETIMEDOUT// 接收消息ssize_tmq_receive(mqd_tmqdes,char*msg_ptr,size_tmsg_len,unsignedint*msg_prio);mqdes:mq_open()返回的队列描述符 msg_ptr:存储接收消息的缓冲区 msg_len:缓冲区大小,必须>=mq_msgsize msg_prio:若非NULL,存储接收消息的优先级 返回值:成功返回接收到的字节数,失败返回-1并设置 errno 说明:始终接收队列中优先级最高的消息// 带超时接收消息ssize_tmq_timedreceive(mqd_tmqdes,char*msg_ptr,size_tmsg_len,unsignedint*msg_prio,conststructtimespec*abs_timeout);abs_timeout:绝对超时时间(基于 CLOCK_REALTIME) 返回值:成功返回接收到的字节数,超时返回-1且 errno 为 ETIMEDOUT// 注册异步通知intmq_notify(mqd_tmqdes,conststructsigevent*notification);mqdes:mq_open()返回的队列描述符 notification:通知方式structsigevent{intsigev_notify;// 通知方式SIGEV_NONE:不通知 SIGEV_SIGNAL:发送信号 SIGEV_THREAD:启动线程intsigev_signo;// 信号编号(SIGEV_SIGNAL 时)unionsigval sigev_value;// 信号附带数据void(*sigev_notify_function)(unionsigval);// 线程函数(SIGEV_THREAD 时)pthread_attr_t*sigev_notify_attributes;// 线程属性};返回值:成功返回0,失败返回-1并设置 errno 说明:每个队列同一时间只能有一个进程注册通知 当队列从空变为非空时,系统向注册进程发送通知 通知发生后注册自动解除,需重新注册// 获取队列属性intmq_getattr(mqd_tmqdes,structmq_attr*attr);mqdes:mq_open()返回的队列描述符 attr:存储属性的结构体指针 返回值:成功返回0,失败返回-1并设置 errno// 设置队列属性intmq_setattr(mqd_tmqdes,conststructmq_attr*newattr,structmq_attr*oldattr);mqdes:mq_open()返回的队列描述符 newattr:新属性(仅 mq_flags 中的 O_NONBLOCK 标志可修改) oldattr:保存修改前的属性,不需要时设为NULL返回值:成功返回0,失败返回-1并设置 errno// 关闭消息队列intmq_close(mqd_tmqdes);mqdes:mq_open()返回的队列描述符 返回值:成功返回0,失败返回-1并设置 errno 说明:关闭描述符,但不删除队列。进程终止时自动关闭所有已打开的队列// 删除消息队列intmq_unlink(constchar*name);name:消息队列名称 返回值:成功返回0,失败返回-1并设置 errno 说明:删除队列名称。若仍有进程打开该队列,队列在所有进程关闭后才被销毁 类似文件系统的 unlink 机制

POSIX信号量 (semaphore.h)

POSIX 信号量相比 System V 信号量,API 更简洁,分为有名信号量(可用于不相关进程间)和无名信号量(基于内存,用于线程或亲缘进程间)。编译时需链接-pthread(无名信号量)或-lrt(部分系统有名信号量)。

有名信号量

// 打开/创建有名信号量sem_t*sem_open(constchar*name,intoflag,.../* mode_t mode, unsigned int value */);name:信号量名称,必须以斜杠开头(如"/mysem") oflag:访问标志 O_CREAT:不存在则创建(需提供 mode 和 value 参数) O_EXCL:与 O_CREAT 连用,信号量已存在则失败 mode:创建权限(如0666),仅在 O_CREAT 时使用 value:信号量初始值 返回值:成功返回信号量指针,失败返回 SEM_FAILED 并设置 errno// 关闭有名信号量intsem_close(sem_t*sem);sem:sem_open()返回的信号量指针 返回值:成功返回0,失败返回-1并设置 errno 说明:关闭信号量,进程终止时自动关闭所有已打开的信号量// 删除有名信号量intsem_unlink(constchar*name);name:信号量名称 返回值:成功返回0,失败返回-1并设置 errno 说明:删除信号量名称。若仍有进程打开,信号量在所有进程关闭后才被销毁

无名信号量

// 初始化无名信号量intsem_init(sem_t*sem,intpshared,unsignedintvalue);sem:指向信号量对象的指针 pshared:共享属性0:仅在同一个进程的线程间共享 非0:可在进程间共享(信号量需位于共享内存区域) value:信号量初始值 返回值:成功返回0,失败返回-1并设置 errno// 销毁无名信号量intsem_destroy(sem_t*sem);sem:指向信号量对象的指针 返回值:成功返回0,失败返回-1并设置 errno 说明:销毁前确保没有线程在等待该信号量 仅对 sem_init 初始化的信号量使用,不可用于有名信号量

通用操作(有名/无名信号量通用)

// P操作 - 等待信号量(阻塞)intsem_wait(sem_t*sem);sem:指向信号量对象的指针 返回值:成功返回0,失败返回-1并设置 errno 说明:将信号量值减1。若值已为0,调用线程阻塞直到值大于0// P操作 - 尝试等待信号量(非阻塞)intsem_trywait(sem_t*sem);sem:指向信号量对象的指针 返回值:成功返回0,失败返回-1且 errno 为 EAGAIN(信号量值为0// P操作 - 带超时等待信号量intsem_timedwait(sem_t*sem,conststructtimespec*abs_timeout);sem:指向信号量对象的指针 abs_timeout:绝对超时时间(基于 CLOCK_REALTIME) 返回值:成功返回0,超时返回-1且 errno 为 ETIMEDOUT// V操作 - 释放信号量intsem_post(sem_t*sem);sem:指向信号量对象的指针 返回值:成功返回0,失败返回-1并设置 errno 说明:将信号量值加1,若有线程在等待则唤醒其中一个// 获取信号量当前值intsem_getvalue(sem_t*sem,int*sval);sem:指向信号量对象的指针 sval:存储信号量当前值的指针 返回值:成功返回0,失败返回-1并设置 errno 说明:返回值为调用瞬间的快照,可能立即过时(仅作调试/监控用途)

POSIX共享内存 (sys/mman.h)

POSIX 共享内存通过内存映射文件(memfd)实现,使用文件描述符操作,比 System V 共享内存的 shmget/shmat 接口更统一。编译时需链接-lrt(部分系统还需-lpthread)。

// 创建/打开共享内存对象intshm_open(constchar*name,intoflag,mode_tmode);name:共享内存对象名称,必须以斜杠开头(如"/myshm"),且不含其他斜杠 oflag:访问标志 O_RDONLY:只读 O_RDWR:读写 O_CREAT:不存在则创建 O_EXCL:与 O_CREAT 连用,对象已存在则失败 O_TRUNC:若对象已存在则将其截断为0长度 mode:创建权限(如0666),仅在 O_CREAT 时使用 返回值:成功返回文件描述符,失败返回-1并设置 errno 说明:shm_open 仅创建对象,大小初始为0,需用 ftruncate 设置大小// 设置共享内存大小intftruncate(intfd,off_tlength);fd:shm_open()返回的文件描述符 length:共享内存大小(字节),建议为页大小(4096)的整数倍 返回值:成功返回0,失败返回-1并设置 errno 说明:新创建的共享内存对象大小为0,必须调用 ftruncate 设置大小后才能映射// 内存映射void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);addr:映射起始地址,通常设为NULL由系统选择 length:映射长度(字节) prot:内存保护标志 PROT_READ:可读 PROT_WRITE:可写 PROT_EXEC:可执行 PROT_NONE:不可访问 flags:映射标志 MAP_SHARED:共享映射,修改对其他进程可见且同步到底层对象 MAP_PRIVATE:私有映射,修改不反映到底层对象(写时复制) MAP_ANONYMOUS:匿名映射,不基于文件,fd 设为-1MAP_FIXED:强制映射到 addr 指定的地址(不推荐) fd:shm_open()返回的文件描述符(MAP_ANONYMOUS 时设为-1) offset:文件偏移量,必须为页大小的整数倍,通常设为0返回值:成功返回映射区域的指针,失败返回MAP_FAILED((void*)-1)并设置 errno// 解除映射intmunmap(void*addr,size_tlength);addr:mmap()返回的映射地址 length:映射长度 返回值:成功返回0,失败返回-1并设置 errno 说明:进程终止时自动解除所有映射// 同步映射区域到磁盘intmsync(void*addr,size_tlength,intflags);addr:映射地址 length:同步长度 flags:同步方式 MS_SYNC:同步等待写入完成 MS_ASYNC:异步发起写入 MS_INVALIDATE:使缓存失效,使后续访问重新从磁盘读取 返回值:成功返回0,失败返回-1并设置 errno// 关闭共享内存对象intclose(intfd);fd:shm_open()返回的文件描述符 返回值:成功返回0,失败返回-1并设置 errno 说明:关闭文件描述符,但不删除共享内存对象,也不解除已有的映射// 删除共享内存对象intshm_unlink(constchar*name);name:共享内存对象名称 返回值:成功返回0,失败返回-1并设置 errno 说明:删除共享内存对象名称。若仍有进程映射该对象,对象在所有映射解除后才被销毁 类似文件系统的 unlink 机制
http://www.jsqmd.com/news/1387954/

相关文章:

  • PKC 第 122 个开关:拷贝个性签名的位置、验证方法与风险边界
  • 法律网站的建设流程详解与专业指南
  • 2026年北京东城区保暖服饰源头工厂靠谱推荐:马员外服饰全产业链实力解析 - 子柔传媒
  • 揭秘中关村网站建设公司:如何避坑与选择真正懂技术的团队
  • LaTeX参考文献管理全攻略:从BibTeX到biblatex,告别手动编号
  • 2026年北京通州区保暖服饰源头工厂靠谱推荐:马员外服饰全产业链实力解析 - 科技快讯
  • 湖南网站建设哪家好:揭秘真正懂业务的本地化建站团队,避坑指南与终极建议
  • 输入设备解耦架构:QKeyMapper如何重构Windows平台的输入交互范式
  • 适合中小团队的DevOps软件怎么选?选型指南与方案推荐
  • 【Bug已解决】[CUDA] GPT-OSS-20B Throughput Optimization 解决方案
  • 2026年济南莱芜区保暖服饰源头工厂靠谱推荐:马员外服饰全产业链实力解析 - 小随科技
  • MySQL数字溢出处理:从SQL模式到数据安全的实战解析
  • 成都空调坏了怎么办?简单到家一站式维修方案来了 - 简单到家
  • MCP多Server架构下AI调用混乱的根源与实战解决方案
  • LangGraph:用状态机与图编排构建复杂AI应用
  • 核心技术人才留不住怎么破?北京华恒智信成功案例
  • Kubernetes上构建高可用Nacos集群:从架构设计到生产部署全解析
  • 2026年北京西城区保暖服饰源头工厂靠谱推荐:马员外服饰全产业链实力解析 - 企业新闻快传
  • Spring Boot核心优势与项目创建实战:从自动装配到最佳实践
  • 网站建设所需基本资料全套清单与避坑指南
  • 高薪招来的人不胜任怎么破?北京华恒智信成功案例
  • Wireshark安装全攻略:Linux与Mac系统权限配置与避坑指南
  • Java命名冲突:从编译原理到依赖管理的实战解决方案
  • PyTorch张量创建与类型转换实战指南
  • 焦作网站建设哪家正规?揭秘正规网站公司背后的核心门道
  • Word图表自动编号与交叉引用:告别手动排版,提升文档效率
  • 双层优化架构在多主体综合能源系统调度中的应用
  • 去i迹处理社媒内容要避哪些坑?隐私、语气与复检指南!
  • 西门子PLC一键手自动切换程序设计与无扰切换实战
  • 旅游网站建设报价单怎么算?2024年最新价格解析与避坑指南,含完整模板