UNIX标准C - 进程之间的通信
一、基本概念
进程间通信IPC:进程之间交换数据的过程叫进程间通信
进程间同性的方式:
简单的进程间的通信:
命令行:父进程通过exec函数创建子进程是可以附加一些数据
环境变量表:父进程通过exec函数创建子进程顺便传递一张环境变量表
信号:父子进程之间可以根据进程号相互发送信号,进行简单通信
文件:一个进程向文件中写入数据,另一个进程从文件读3出来
命令行、环境变量只能单向传递,信号太过于简单,文件不能实时。
传统的进程之间通信方式:管道
二、管道
1.管道是一种古老的通信方式(基本上不再使用)
2.早期的管道是一种半双工,现在基本上是全双工的
3.有名管道(这种管道是文件方式存在的)
创建管道文件:
命令:mkfifo
函数:int mkfifo(const char *pathname, mode_t mode);
管道通信的编程模式:
进程a 进程b
创建管道mkfifo
打开管道文件open 打开管道open
写/读数据read/write 读/写数据read/write
关闭管道 关闭管道
4.无名管道:由内核帮助创建,只返回管道的文件描述符,看不到管道文件。但这种管道只能使用于fork()创建的父子进程之间。
int pipe(int pipefd[2])
pipefd[0] 用来读数据
pipefd[1] 用来写数据
XSI通信方式:X/open 计算机制造商组织。
共享内存、消息队列、信号量
三、XSI IPC进程间通信
1.XSI通信是靠内核的IPC对象进程通信
2.每一个IPC对象都有一个IPC标示(类似文件描述符),它是一个非负整数。
3.IPC对象必须要先创建,创建完才能进行获取、设置、操作、删除。
4.创建IPC对象必须要提供一个健值(key_t),健值是创建、获取IPC对象的依据。
5.产生健值的方式:
固定的字面符:1980014
使用函数计算:健值 = ftok(项目路径,项目id) ftok(const char *pathname,int proj_id);
使用宏让操作系统随机分配:IPC_PRIVTE
必须把获取到IPC对象标示符记录下来,告诉其他进程
6.XSI可以创建的IPC对象:共享内存、消息队列、信号量
四、共享内存
1、由内核维护一块共享的内存区域,其他进程把自己的虚拟地址映射到这块内存,然后多个进程之间就可以共享这块内存
2、这种进程间通信的好处是不需要信息复制,是进程间通信最快的一种方式。
3、但这种通信方式会面临同步的问题。需要与其他的通信配合,最合适的就是信号。
共享内存的编程模式:
1.进程之间要约定一个健值
进程A 进程B
创建共享内存
加载共享内存 加载共享内存
卸载共享内存 卸载共享内存
销毁共享内存
int shmget(key_t key,size_t size,int shmflg)
功能:创建共享内存
size:共享大小 尽量是4096的倍数
shmflg:IPC_CREAT|IPC_EXCL
返回值:IPC对象标志符
void *shmat(int shmid,const void * shmaddr,int shmflg)
功能:加载共享内存(进程的虚拟地址与共享的内存映射)
shmid:shmget的返回值
shmaddr:进程提供的虚拟地址,如果为NULL,操作系统会自动选择
shmflg:
SHM_RDONLY:限制内存的权限为只读
SHM_REMAP:映射已经存的共享
SHM_RND:当shmaddr为空时自动分配
SHMLBA:shmaddr的值不能为空
返回值:映射后的虚拟地址
int shmdt(const void* shmaddr);
功能:卸载共享内存(进程的虚拟地址与共享的内存取消映射关系)
int shmctl(int shmid,int cmd,struct shmid_ds* buf)
功能:控制/销毁共享内存
cmd:
IPC_STAT:获取共享内粗的属性
IPC_SET:设置共享内存的属性
IPC_RMID:删除共享内存
IPC_INFO:获取贡献内存的信息
共享内存是进程见通信最快的一种,因此数据没有复制过程,但是无法得知进程之间的数据写入和读取,需要其他的通信方式的配额
五、消息队列
1.消息队列是一个由系统内核负责存储和管理、并通过IPC对象标示符获取的数据链表。
int msgget(key_t key, int msgflg);
功能:创建或获取消息队列
msgflg:
创建:IPC_CREAT|IPC_EXCL|0777
获取:0
返回:IPC对象标志符
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向消息队列发送消息
msqid:msgget的返回值
msgp:消息(消息类型加消息内容)的首地址
msgsz:消息内容的长度
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
功能:从消息队列接受消息
msgp:存储消息的缓冲区
msgsz:要接受的消息长度
msgtyp:消息的类型,包含在消息的前4个字节。
msgflg:
MSG_NOERROR:当消息的实际长度比msgsz还要长的话,
则按照msgsz长度截取再发送。否则产生错误。
MSG_NOWAIT:如果要接的消息不存在,直接返回
否则阻塞等待。
MSG_EXCEPT:从消息队列中接受第一个不
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:控制/销毁消息队列
cmd:
IPC_STAT:获取消息队列的属性
IPC_SET:设置消息队列的属性
IPC_RMID:删除消息队列
六、IPC相关命令:
ipcs -m 察看共享内存
ipcrm -m id 删除共享内存
ipcs -q 察看消息队列
ipcrm -q id 删除消息队列
7、信号量
信号量(信号灯),可以当作进程与进程之间共享的全局变量。一般用来为共享的资源计数。
信号量的使用方式:
1.进程A,创建信号量,并设置初始化(设置资源的数)
2.进程B,获取信号量,查询信号量(查询剩余资源的数量)。减少信号量(使用资源),增加信号量(资源使用完毕归还)
3.当一个进程尝试减少信号量时,如果不能减(资源使用完毕),则进程可以进入等待状态。
当信号量能够被减时,(其他进程把资源还回来了),进程会被唤醒。
函数
int semget(key_t key, int nsems, int semflg);
功能:创建信号量或获取信号量
nsems:信号量的数量
semflg:
IPC_CREAT|IPC_EXCL|0644
返回值:IPC对象标志符
int semop(int semid, struct sembuf *sops, unsigned nsops);
功能:对信号量增加或减少
struct sembuf
{
unsigned short sem_num; 信号的编号
short sem_op; 对信号的处理
short sem_flg;
如果信号量当前是0,函数立即返回。
IPC_NOWAIT:会阻塞
}
int semctl(int semid,int semnum,int cmd,...);
功能:对信号量控制或释放
semnum:信号量的编号
cmd:
IPC_SET 设置信号量的属性
IPC_STAT 获取信号量的属性
IPC_RMID 删除信号量
IPC_INFO 获取信号量的信息
UNIX标准C - 进程之间的通信的更多相关文章
- day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信
day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...
- Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信
Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...
- c# IPC实现本机进程之间的通信
IPC可以实现本地进程之间通信.这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通 ...
- python全栈开发 * 进程之间的通信,进程之间数据共享 * 180726
进程之间的通信(IPC)队列和管道一.队列 基于管道实现 管道 + 锁 数据安全(一).队列 队列遵循先进先出原则(FIFO) 多用于维护秩序,买票,秒杀 队列的所有方法: put()(给队列里添加数 ...
- 进程之间的通信(multiprocess.Queue)
一.进程间通信 进程之间的数据是相互隔离的,例如 from multiprocessing import Process def task(): global n # 声明全局变量 n = 999 p ...
- 《Python》进程之间的通信(IPC)、进程之间的数据共享、进程池
一.进程间通信---队列和管道(multiprocess.Queue.multiprocess.Pipe) 进程间通信:IPC(inter-Process Communication) 1.队列 概念 ...
- python进程之间的通信——Queue
我们知道进程之间的数据是互不影响的,但有时我们需要在进程之间通信,那怎么办呢? 认识Queue 可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息 ...
- python网络编程中互斥锁与进程之间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- Linux_进程之间的通信
一.进程间的通信 1️⃣:进程间通信(IPC:Inter Process Communication) 2️⃣:进程之间通信方式: 同一主机 共享内存 信号:Signal 不同主机 rpc:remot ...
随机推荐
- OpenTSDB查询和写入毫秒级数据
由于OpenTSDB没有支持Java的SDK进行调用,所以基于Java开发OpenTSDB的调用将要依靠HTTP请求的方式进行. 1.毫秒级数据写入 /api/put:通过POST方式插入JSON格式 ...
- Ubuntu下火狐浏览器播放视频出现解码问题
问题描述 点击视频播放按钮,视频不会出现缓冲条,也没任何提示,视频界面就一直是黑屏的状态.右键该视频界面,选择检查元素,点击控制台,发现如下问题: The video on this page can ...
- Balloon Robot ZOJ - 3981
大意: n个参赛队, m个座位, 一共交了p次题, 一个机器人每秒钟会从位置$i$走到$i+1$, 若在$m$直接走到$1$, 当走到一个队伍就给该队应得的气球. 对于每道题, 假设交题时间$t_a$ ...
- C# 并行编程之早起三件事
故事背景 透着纱的窗外的阳光, 又是一个星期一. 慢慢来 一看时间, 还早, 那么蹦跶起来 穿衣 刷牙 洗脸 用代码来说的话, 应该是这样: // Program.cs using System; u ...
- Centos下安装nc命令工具安装以及使用
1)netcat(nc)是一个简单而有用的工具,被誉为网络安全界的“瑞士军刀”,不仅可以通过使用TCP或UDP协议的网络连接读写数据,同时还是一个功能强大的网络调试和探测工具,能够建立你需要的几乎所有 ...
- MEWKit:Cryptotheft 的最新武器
By:Yonathan Klijinsma 译者:知道创宇安全服务团队.404区块链安全团队 介绍 当谈到加密货币时,会联想到加密货币巨大的价格波动,交易违约.赎金勒索的情况以及许多不同种类的货币.虚 ...
- SIP协议 会话发起协议(二)
SIP - 响应码 SIP响应是由用户代理服务器(UAS)或SIP服务器生成的用于回复客户端生成的请求的消息.这可能是一个正式的确认,以防止UAC转发请求. 响应可能包含UAC所需的一些额外的信息头字 ...
- CentOS7 minimal安装初始化配置
个人喜好最小化安装系统,需要配置的如下信息 1.更改网络配置为固定ip #vi /etc/sysconfig/network-scripts/ifcfg-eth0BOOTPROTO="sta ...
- 关于myBatis配置中的一些注意事项
最近在学习mybatis,在网上查阅资料,并按照别人的范例来测试,总会出一些错误,这里把配置过程中的一些注意事项梳理一下. 一.导包(用eclipse开发) 1.如果你新建的是普通的project,需 ...
- ELF程序头部及程序加载
程序头部 程序头部描述与程序执行直接相关的目标文件结构信息.用来在文件中定位各个段的映像.同时包含其他一些用来为程序创建进程映像所必需的信息. 可执行文件或者共享目标文件的程序头部是一个结构数组,每个 ...