进程间通讯
1.进程间通讯概述进程间通讯---IPC2.管道通讯原理IPC的方式通常有管道包括无名管道和命名管道、消息队列、信号量、共享存储、Socket、Streams等。其中Socket和Streams支持不同主机上的两个进程IPC。一.管道管道通常指无名管道是UNIX系统IPC最古老的形式。1.特点1.它是半双工的具有固定的读端和写端。----管道中的数据读走就没了2.它只能用于具有亲缘关系的进程之间通信。3.它可以看成一种特殊文件对于它的读写可以使用普通的read、write等函数。但他不是普通文件并不属于任何文件系统并且只存于内存中。2.原型#include unistd.h int pipe(int pipefd[2]);//成功返回0失败返回-1当一个管道建立时它会创建两个文件描述符fd[0]为读而打开fd[1]为写而打开。要关闭管道只需将这两个文件描述符关闭即可若要数据从父进程流向子进程则需关闭父进程的读端fd[0]与子进程的写端fd[1]反之则子流向父。3.管道编程实战代码如下#include stdio.h #include unistd.h #include string.h #include stdlib.h int main() { int fd[2]; int pid; char readBuf[128]; // int pipe(int pipefd[2]); if(pipe(fd) -1) { printf(pipe create failed\n); } pid fork(); if(pid 0) { printf(create child failed\n); } else if(pid 0) { printf(this is father\n); close(fd[0]); write(fd[1],hello from father,strlen(hello from father)); wait(NULL); } else if(pid 0) { printf(this is child\n); close(fd[1]); read(fd[0],readBuf,128); printf(read from father,readBuf:%s\n,readBuf); exit(0); } return 0; }运行结果4.创建命名管道二.FIFOFIFO也称为命名管道它是一种文件类型。1.特点1.FIFO可以在无关的进程之间交换数据与无名管道不同。2.FIFO与路径名与之相关联它以一种特殊设备文件形式存在于文件系统中。2.原型#include sys/types.h #include sys/stat.h int mkfifo(const char *pathname, mode_t mode);//返回值成功返回0失败返回-1其中mode参数与open函数中的mode相同。一旦创建了一个FIFO就可以用一般的文件I/O函数操作它。#include sys/types.h #include sys/stat.h #include stdio.h #include errno.h int main() { if((mkfifo(./file,0600) -1) (errno EEXIST)) { printf(mkfifo failure!\n); perror(why); } return 0; }5.命名管道的数据通讯编程实现#include sys/types.h #include sys/stat.h #include stdio.h #include errno.h #include fcntl.h int main() { if((mkfifo(./file,0600) -1) (errno EEXIST)) { printf(mkfifo failure!\n); perror(why); } int fd open(./file,O_RDONLY); printf(open success!\n); return 0; }运行结果如下发现程序阻塞了。当open一个FIFO时是否设置非阻塞标志O_NONBLOCK的区别1.若没有指定O_NONBLOCK默认只读open要阻塞到某个其他进程为写而打开此FIFO类似的只写open要阻塞到某个其他进程为读而打开它。2.若指定了O_NONBLOCK则只读open立即返回。而只写open将出错返回-1如果没有进程已经为读而打开该FIFO其errno置ENXIO。write#include sys/types.h #include sys/stat.h #include stdio.h #include errno.h #include fcntl.h #include string.h int main() { char *str message from fifo; int fd open(./file,O_WRONLY); printf(write open success!\n); while(1) { write(fd,str,strlen(str)); sleep(1); } close(fd); return 0; }read#include sys/types.h #include sys/stat.h #include stdio.h #include errno.h #include fcntl.h int main() { char buf[30]; int nread; if((mkfifo(./file,0600) -1) (errno ! EEXIST)) { printf(mkfifo failure!\n); perror(why); } int fd open(./file,O_RDONLY); printf(open success!\n); while(1) { nread read(fd,buf,30); printf(read %d byte from fifo,context:%s\n,nread,buf); } close(fd); return 0; }只有当write打开之后read才能继续执行6.消息队列的通讯原理三.消息队列消息队列是消息的链接表存放在内核中。一个消息队列由一个标识符来标识。1.特点1.消息队列是面向记录的其中的消息具有特定的格式以及特定的优先级。2.消息队列独立于发送与接收过程。进程终止时消息队列及其内容不会被删除。3.消息队列可以实现消息的随机查询消息不一定要以先进先出的次序读取也可以按消息的类型读取。7.消息队列相关api2.原型#include sys/msg.h //创建或打开消息队列:成功返回队列0失败返回队列-1 int msgget(key_t key, int msgflg); //添加消息:成功返回0失败返回-1 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); //读取消息:成功返回消息数据的长度失败返回-1 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); //控制消息队列:成功返回0失败返回-1 int msgctl(int msqid, int cmd, struct msqid_ds *buf);8.消息队列编程收发数据代码接收#include stdio.h #include sys/types.h #include sys/ipc.h #include sys/msg.h #include string.h // int msgget(key_t key, int msgflg); // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); // ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); // int msgctl(int msqid, int cmd, struct msqid_ds *buf); struct msgbuf { long mtype; /* message type, must be 0 */ char mtext[128]; /* message data */ }; int main() { //huo qu struct msgbuf readBuf; struct msgbuf sendBuf {988,thank you for reach}; int msgId msgget(0x1235,IPC_CREAT|0777); if(msgId -1) { printf(get que failure!\n); } msgrcv(msgId,readBuf,sizeof(readBuf.mtext),888,0); printf(read from que:%s\n,readBuf.mtext); msgsnd(msgId,sendBuf,strlen(sendBuf.mtext),0); return 0; }发送#include stdio.h #include sys/types.h #include sys/ipc.h #include sys/msg.h #include string.h // int msgget(key_t key, int msgflg); // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); // ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); // int msgctl(int msqid, int cmd, struct msqid_ds *buf); struct msgbuf { long mtype; /* message type, must be 0 */ char mtext[128]; /* message data */ }; int main() { //huo qu struct msgbuf sendBuf {888,this is message from quen}; struct msgbuf readBuf; int msgId msgget(0x1235,IPC_CREAT|0777); if(msgId -1) { printf(get que failure!\n); } msgsnd(msgId,sendBuf,strlen(sendBuf.mtext),0); printf(send over\n); memset(readBuf.mtext,128,\0); msgrcv(msgId,readBuf,sizeof(readBuf.mtext),988,0); printf(return from Get:%s\n,readBuf.mtext); return 0; }9.键值生成及消息队列移除key_t ftok(const char *pathname, int proj_id);其中参数fname是指定的文件名这个文件必须是存在的而且可以访问的。id是子序号它是一个8bit的整数。即范围是0~255。当函数执行成功则会返回key_t键值否则返回-1。在一般的UNIX中通常是将文件的索引节点取出然后在前面加上子序号就得到key_t的值。添加代码如下添加消息队列key_t key; key ftok(.,z); printf(key %x\n,key); int msgId msgget(key,IPC_CREAT|0777);删除消息队列msgctl(msgId,IPC_RMID,NULL);10.共享内存概述使用步骤创建共享内存/打开 --- 映射 --- 数据交换 --- 释放共享内存 --- 干掉共享内存11.共享内存编程实现共享内存相关api//创建或获取一个共享内存成功返回共享内存ID失败返回-1 int shmget(key_t key, size_t size, int shmflg); //连接共享内存到当前进程的地址空间成功返回指向共享内存的指针失败返回-1 void *shmat(int shmid, const void *shmaddr, int shmflg); //断开与共享内存的连接成功返回0失败返回-1 int shmdt(const void *shmaddr); //控制共享内存的相关信息成功返回0失败返回-1 int shmctl(int shmid, int cmd, struct shmid_ds *buf);读#include sys/ipc.h #include sys/shm.h #include stdlib.h #include stdio.h #include string.h // int shmget(key_t key, size_t size, int shmflg); // void *shmat(int shmid, const void *shmaddr, int shmflg); int main() { int shmid; char *shmaddr; key_t key; key ftok(.,1); shmid shmget(key,1024*4,0); if(shmid -1) { printf(shmget no ok!\n); exit(-1); } shmaddr shmat(shmid,0,0); printf(shmat ok\n); printf(data:%s\n,shmaddr); sleep(5); shmdt(shmaddr); printf(quit\n); return 0; }写#include sys/ipc.h #include sys/shm.h #include stdlib.h #include stdio.h #include string.h // int shmget(key_t key, size_t size, int shmflg); // void *shmat(int shmid, const void *shmaddr, int shmflg); int main() { int shmid; char *shmaddr; key_t key; key ftok(.,1); shmid shmget(key,1024*4,IPC_CREAT|0666); if(shmid -1) { printf(shmget no ok!\n); exit(-1); } shmaddr shmat(shmid,0,0); printf(shmat ok\n); strcpy(shmaddr,hello world); sleep(5); shmdt(shmaddr); shmctl(shmid,IPC_RMID,0); printf(quit\n); return 0; }查看系统中有哪些共享内存ipcs -m删除系统中共享内存12.信号概述对于Linux来说实际信号是软中断许多重要的程序都需要处理信号。信号为Linux提供了一种处理霁步事件的方法。比如终端用户输入了ctrlc来中断程序会通过信号机制停止一个程序。信号的处理有三种方法分别是:忽略、捕捉和默认动作13.信号编程信号处理函数的注册1.入门版函数 signal2.高级版函数 sigaction信号处理发送函数1.入门版kill2.高级版sigqueue*************************************************kill -l*************************************************让 ctrl c 无效的程序原因分析信号处理函数在捕捉到信号时候让其执行 handler() 函数程序。使用如下方式结束进程判断 ctrl C 和 kill 9 和 kill 10 可不可以结束进程程序如下#include signal.h #include stdio.h // typedef void (*sighandler_t)(int); // sighandler_t signal(int signum, sighandler_t handler); void handler(int signum) { printf(get signum %d\n,signum); switch(signum) { case 2: printf(SIGINT\n); break; case 9: printf(SIGKILL\n); break; case 10: printf(SIGUSR1\n); break; } printf(never qiut\n); } int main() { signal(SIGINT,handler); signal(SIGKILL,handler); signal(SIGUSR1,handler); while(1); return 0; }运行结果如下自己编程杀死进程代码#include signal.h #include stdio.h #include sys/types.h #include string.h // typedef void (*sighandler_t)(int); // sighandler_t signal(int signum, sighandler_t handler); int main(int argc,char **argv) { int signum; int pid; char cmd[128] {0}; signum atoi(argv[1]); pid atoi(argv[2]); printf(num %d,pid %d\n,signum,pid); // 法一 // kill(pid,signum); // // 法二 // sprintf(cmd,kill -%d %d,signum,pid); // system(cmd); // // // printf(send signal ok\n); return 0; }16.信号量概述信号量与已经介绍过的IPC结构不同它是一个计数器。信号量用于实现进程间的互斥与同步而不是用于存储进程间通信数据。1.特点1.信号量用于进程间同步若要在进程间传递数据需要结合共享内存。2.信号量基于操作系统的PV操作程序对信号量的操作都是原子操作。3.每次对信号量的PV操作不仅限于对信号量值加1减1而且可以加减任意正整数。4.支持信号量组。2.原型最简单的信号量是只能取0和1的变量这也是信号量最常见的一种形式叫做二值信号量(Binary Semaphore)。而可以取多个正整数的信号量被称为通用信号量。Linux下的信号量函数都是在通用的信号量数组上进行操作而不是在一个单一的二值信号量上进行操作。//创建或获取一个信号量组若成功返回信号量集ID失败返回-1 int semget(key_t key, int nsems, int semflg); //对信号量组进行操作改变信号量的值成功返回0失败返回-1 int semop(int semid, struct sembuf *sops, unsigned nsops); //控制信号量的相关信息 int semctl(int semid, int semnum, int cmd, ...);

相关新闻

X电容与Y电容,看这一篇就够了

X电容与Y电容,看这一篇就够了

目录: 一、X电容与Y电容介绍 1、简介 2、X电容 3、Y电容 二、X电容与Y电容的容值选取 1、X电容容值计算 2、Y电容容值计算 三、实际应用案例 1、汽车电子应用 2、X电容放电电路

2026/7/23 18:10:26 阅读更多 →
服务器六层板单一电源层架构下PDN优化方案

服务器六层板单一电源层架构下PDN优化方案

服务器硬件普遍采用多相 Buck 降压方案,CPU、内存、各类芯片存在多组独立电源轨,瞬时电流变化剧烈,di/dt 极高。六层板仅有一层专用电源平面,对比八层板可设置双层电源层的架构,电源分配网络设计约束显著增加。很多设计…

2026/7/23 18:10:26 阅读更多 →
软路由系统 --- VMware安装与配置OpenWRT

软路由系统 --- VMware安装与配置OpenWRT

目录: OpenWrt安装与配置一、下载OpenWRT映像二、img转换vmdk格式三、创建虚拟机(OpenWRT)四、启动系统(OpenWRT)五、配置网络信息(LAN、WAN)六、登录OpenWRT后台管理界面一、下载OpenWRT映像 OpenWrt映像…

2026/7/23 18:09:26 阅读更多 →

最新新闻

第 13 篇:Java 对接通义千问大模型,性能优化全攻略 (Java+AI 落地实战系列 | 并发可控 | 响应耗时降低 60%)

第 13 篇:Java 对接通义千问大模型,性能优化全攻略 (Java+AI 落地实战系列 | 并发可控 | 响应耗时降低 60%)

第 13 篇:Java 对接通义千问大模型,性能优化全攻略 (Java+AI 落地实战系列 | 并发可控 | 响应耗时降低 60%) 本文是《Java+AI 落地实战 从入门到生产级》系列第 9 篇 往期回顾: 第1篇:Java程序员学AI/转AI全指南,从CURD到AI应用工程师(零算法,4周落地) 第2篇:Java …

2026/7/23 18:25:32 阅读更多 →
计算机毕业设计之基于C#的身材管理系统

计算机毕业设计之基于C#的身材管理系统

信息技术是当今社会发展的重要方向之一,它已经深入到各个行业中。随着计算机技术的发展,信息技术已经从传统的数据处理转变为网络信息的处理和交互。在管理方面,通过信息管理技术,系统可以快速的处理大量的数据,并且能…

2026/7/23 18:25:32 阅读更多 →
多模型统一接入 + 智能体编排 + 真 SSE 流式,这个开源的 AI 网关全干了

多模型统一接入 + 智能体编排 + 真 SSE 流式,这个开源的 AI 网关全干了

AI Gateway Pro — 企业级多模型 AI 智能网关,统一接入、技能编排、熔断降级、开箱即用 一个能把多个 AI 模型厂商(OpenAI、豆包、Claude…)统一管起来的网关平台,带智能体搭建、技能编排、SSE 真流式对话、熔断降级链&#xff0c…

2026/7/23 18:25:32 阅读更多 →
AI模型选错=项目延期3个月?资深AI架构师披露开发适配性评估四维矩阵(精度/时延/量化支持/文档完备度)

AI模型选错=项目延期3个月?资深AI架构师披露开发适配性评估四维矩阵(精度/时延/量化支持/文档完备度)

更多请点击: https://kaifayun.com 第一章:AI模型选错项目延期3个月?资深AI架构师披露开发适配性评估四维矩阵(精度/时延/量化支持/文档完备度) 选型失误是AI落地中最隐蔽却最具破坏性的风险。某智能质检项目因选用未…

2026/7/23 18:25:32 阅读更多 →
【性能测试】Jmeter录制脚本及服务器资源监控教程

【性能测试】Jmeter录制脚本及服务器资源监控教程

Jmeter录制测试脚本 windows电脑设置 jmeter/bin文件夹中jmeter的安全证书 谷歌浏览器->隐私与安全->管理证书->上传jmeter安全证书 电脑->设置->代理 Jmeter录制配置 测试计划->非测试元件->Http(s)测试脚本记录器-> 打开windows代理&#xf…

2026/7/23 18:25:32 阅读更多 →
嵌入式USB设备开发实战:从描述符构建到事件回调处理

嵌入式USB设备开发实战:从描述符构建到事件回调处理

1. USB设备开发:从协议栈到应用层如果你正在开发一个嵌入式USB设备,无论是自定义的HID设备、音频设备,还是大容量存储设备,最终都绕不开与USB协议栈的深度交互。USB协议本身很复杂,但幸运的是,成熟的MCU厂商…

2026/7/23 18:24:32 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻