IPC

来源:互联网 发布:国家顶级域名 编辑:程序博客网 时间:2024/05/17 23:44

IPC inter-Process Communication 不同process之间相互传输数据

举例:
Process A 把一些数据写在file里面 然后 Process B 从file里面读出来 这就是一个IPC

Process A 通知Process B 跟它说 你可以开始做事情了 这也是一种IPC 协同控制

-------------------------------------------------------------------------------------------------------------

常见的IPC方式

File

FIFO(Named Pipe)

Signal

Semaphore

Pipe(有亲属关系的进程 FIFO 任意进程)

Message queue(asynchronous 一个档案)

Shared memory(内存共享 一块buffer 背后也是一个文档  把内存映射到那个档案 大家mapp 同一块区 传递咨询)

Socket(跨服务器)

-----------------------------------------------------------------------------------------------------------------------------------------------------------

File 一个process把数据卸载档案里 其他process读取

优点

就算关机 内容还是存在

可以一对多分享(对立 pipe 一对一)

简单 大概没有比这个更基本方法


缺点

自己要做通知的动作 读取者很难知道什么时候有新数据产生 或者去hook file system

要如何指定某个数据只给某个reader

----------------------------------------------------------------------------------------------------------------------------------------------

FIFO named Pipe

用mkfifo()建立特殊的格式File

用file I/O 操作达到数据传输 (一个读 一个写)

最后记得 remove/unlink 这个file(不然有尸体 0Kbyte)

优点

blocking  可以做到写入等待 直到对方读取数据

简单直接 毕竟可以用基本 File I/O(fread fwrite)

缺点

一次只能对一个 数据被读取 其他人读不到

档案名称冲突问题

必须预先知道数据size

----------------------------------------------------------------------------------------------------------------------------------------------

FIFO named pipe 实例

int nInput[2]=5={3,5};

int fd=0, result=0;

mkfifo(fileA, 0666); //建立FIFO


//送出两个int  会等在write 直到有人接收

fd=open(fileA, O_WRONLY);

write(fd, nInput, sizeof(int)*2);

close(fd);


//从fileB 读取结果

fd=open(fileB, O_RDONLY);

read(fd, &result, sizeof(int));

close(fd);

printf("result=%d\n",result);

unlink(fileA);

unlink(fileB);

------------------------

int nInput[2], result=0, fd=0;

mkfifo(fileB, 0666); //建立FIFO


//从file A 读取两个int

fd=open(fileA, O_RDONLY);

read(fd, nInput, sizeof(int)*2);

close(fd);


//相加产生结果

result=nInput[0]+nInput[1];


//将result写入fileB

//会等在write直到有人接收

fd=open(fileB, O_WRONLY);

write(fd, &result, sizeof(int));

close(fd);

 

//如果先做write  write会block在那边 直到有人read

//如果先read read会不会卡在那边?

 这样程序有问题 read不一定会等待的 只有write会等待 一定要注意顺序

---------------------------------------------------------------------------------------------------------------------------------------------------

Signal

只能用来通知 无法传输数据

blocking mode 等待

优点

一次可以等待多个signal

一次可以通知多个signal

可以用来传输系统命令 例如SIGKILL

缺点

不能传输数据

---------------------------------------------------------------------------------------------------------------------------------------

Signal当event实例

#include<stdio.h>

#include<stdlib.h>

#include<signal.h>


void **aa(void *arg){

  pid_t ppid =0;

  //取得parent pid

  //做完 signal通知

  kill(ppid, SIGUSR1);

}


main(){

  pthread_t tid;

  sigset_t set;

  

  //init set(只等待SIGUSR1)

  sigemptyset(&set);

  sigaddset(&set, SIGUSR1);

  //建立thread_aa

  pthread_create(&tid, NULL, aa, NULL);

  //等待aa结束的signal

  //aa做完了 可以继续往下

  //...

}

----------------------------------------------------------------------------------------

semaphore

只能用来通知 无法传输数据

尤其适合解决PV problem

binary semaphore可以当Mutex使用(同一个时间段 只有一个可以运行这一段 不会有其他人来打算 互斥锁)


优点

适合一对多 适合多对多

缺点

不能传输数据


使用sem_wait() sem_trywait()当消费者

消费者一次把resource count 减1

resource count =0的时候 消费者睡觉


用sem_post()当生产者

*生产者不会真的睡觉

*连上限都没有

*生产者要睡觉 要自己想办法


单纯使用sem_init() + fork()  Parent跟Child 将不会共用同一个semaphore 要加上shared memory 配合使用 这是个常见陷阱

------------------------------------------------------------------------------------------------------------

semaphore取同样的名字 不同process之间可以共用semaphopre 不需要亲子关系

 或者同一个进程的不同thread 共用同一个semaphore来调度的

#define SEM_NAME "sem"

sem_t *sem = NULL;

//建立semaphore

sem=sem_open(SEM_NAME, O_CREAT, S_IRWXU, 0);

//增加semaphore (+1)

sem_post(sem);

//离开前的释放资源

sem_close(sem);

sem_unlink(SEM_NAME);

sem =NULL;

---------------------------------------

#define SEM_NAME "sem"

sem_t *sem=NULL;

//建立semaphore

sem=sem_open(SEM_NAME, O_CREAT, S_IRWXU, 0);

//等待semaphpre

sem_wait(sem);

//离开前的释放资源

sem_close(sem);

sem=NULL; 














原创粉丝点击