IPC2
来源:互联网 发布:沙箱软件 编辑:程序博客网 时间:2024/06/07 20:39
Pipe
只能在parent与child之间 或者是child与child之间的互传数据
读取时 blocking mode 等待
单方向的IPC 方式
优点
不用处理race condition (一个写 一个接收 不需要第三者来抢数据)
缺点
只适合与parent vs Child 或者是 Child vs Child
----------------------------------------------------------------------------------------------------------------------------------
Pipe 实例
int pPipe[2], cPipe[2], nInput[2], sum=0;
//假设pPipe是child=>parent cPipe 是 Parent=>Child
pipe(pPipe);
pipe(cPipe);
if((pid=fork())==0){ //child process
read(cPipe[0], nInput, 8);
sum=nInput[0]+nInput[1];
write(pPipe[1],&sum, 4);
}
else{ //Parent process
nInput[0]=3; nInput[1]=5;
write(cPipe[1], nInput, 8); //传两个init给child
read(pPipe[0], &sum, 4); //取得回传的结果
printf("result=%d", sum);
}
-------------------------------------------------------------------------------------------------------------------------------
Message queue
用非同步模式来传输接收数据
msgget(建立) msgsnd(传送) msgrcv(接收) msgctl(释放)
如果是使用IPC_NOWAIT 将变成non-blocking mode(如果是wait的话 上面四个msg 没成功就等待)
有些进阶的MQ 甚至可以跨服务器
优点
可以指定接受者
可以非同步传送与接收
缺点
Message Queue 储存容量有上限 单笔最大8192bytes 最多存放16384笔
最后要记得删除临时档案
-----------------------
struct msgBuf{int type; int data;};
key_t mqKey;
struct msgBuf msg;
int mqID =0;
mqKey=ftok("msg.txt", ‘b’); //建立key
mqID = msgget(mqKey, 0660 | IPC_CREAT);
//传输数据并指定type=1
msg.type=1;msg.data=nInput[0];
msgsnd(mqID, &msg, sizeof(msg), 0);
msg.type=1; msg.data=nInput[1];
msgsnd(mqID, &msg, sizeof(msg), 0);
//指定接收type=2的数据(回传结果)
msgrcv(mqID, &msg, sizeof(msg),2, 0);
result = msg.data;
msgctl(mqID, IPC_RMID, NULL); //释放资源
--------------------------------------------
struct msgBuf{int type; int data;};
key_t mqKey;
struct msgBuf msg;
int mqID =0;
mqKey=ftok("msg.txt", ‘b’); //建立key
mqID = msgget(mqKey, 0660 | IPC_CREAT);
msgrcv(mqID, &msg, sizeof(msg), 1, 0);
nInput[0] = msg.data;
msgrcv(mqID, &msg, sizeof(msg), 1, 0);
nInput[1] = msg.data;
shared memory
大家共用同一块内存来交换数据
shmget(建立) shmdt(传送)shmat(接收) shmctl(释放)
优点
可以用在多对对
速度最快的方式
缺点
要自己处理所有的race condition问题
-------------------------------
key_t shmKey;
int shmID =0, result=0, nInput[2]={3,5}, *pBuf;
shmKey=ftok("msg.txt", 'b'); //建立Key
//设定shm大小=8,设定对应到的pBuf
shmID=shmget(shmKey, 8, MODE_MASK);
pBuf=shmat(shmID, NULL, 0);
//写入两个int到shm
memcpy(pBuf, nInput, 8);
shmdt(pBuf);
sem_post(semA); //A通知B 两个int好了
sem_wait(semB); //A等待B 通知结果
//从shm中取得结果(放在pBuf)
pBuf=shmat(shmID, NULL, 0);
memcpy(&result, pBuf,4); //取出result
msgctl(mqID, IPC_RMID, NULL); //释放资源
--------------------------------
key_t shmKey;
int shmID=0, result=0, nInput[2], *pBuf);
shmKey=ftock("msg.txt", ‘b’); //建立key
//设定shm大小=8 设定对应到pBuf
shmID=shmget(shmKey, 8, MODE_MASK);
pBuf=shmat(shmID, NULL, 0); //等待A通知
//从shm取得8Bytes
memcpy(nInput, pBuf, 8);
result=nInput[0]+nInput[1];
//相加的结果写回shm
memcpy(pBuf, &result, 4);
shmdt(pBuf);
sem_post(semB); //通知A结果已经出来了
---------------------------------------------------------------------------------------------------------------------------------------
Socket
透过网路传输数据的最基本方式
各种数据类型 大小都适用
优点
可以一对一(TCP) 或者一对多(UDP)
可以跨服务器
缺点
socket programming 稍微复杂一些
--------------------------------------------------------------------------------------------------------------------------------------
IPC 比较
File 可以多对多 自行处理race condition 关机以后档案还在
FIFO 一对一 先进先出 任意两个process之间简单传数据
Signal 可一对多 无法传数据 简单的信号通知
Semaphore 可多对多 无法传输数据 PV problem
pipe 一对一亲缘进程 先进先出 父子进程 兄弟进程
MQ 可以多对多 可以指定接受者 数据量有限(8192bytes) 非同步 数据会被保存 可以挑选自己要的数据
shared memory 可多对多 自行处理race condition 速度最快 灵活度高
socket 一对一TCP 一对多UDP 同台电脑内 大炮打小鸟 网路传输
-------------------------------------------------------------------------------------------------------------------------------------