Linux 进程间通信
来源:互联网 发布:windows 2008 server 编辑:程序博客网 时间:2024/06/14 17:27
进程间通信
- 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。
- 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。
- 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件。
- 资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。
- 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
信号
通过注册信号与全局变量的结合达到进程间通信
优点:实时,不阻塞
缺点:不安全,内容固定
案例:
void func(int n){ printf("ping\n"); // how to send signal 4 to the second process?}void func2(int n){ printf("pong\n"); // how to send signal 3 to the first process?}int main(){ pid_t pid; int i; for(i = 0; i < 2; i++){ pid = fork(); if(pid == 0){ if(i == 0){ signal(3, func); }else{ signal(4, func2); } while(1); }else{ if(i == 1){ sleep(3); // how to send signal 3 to the first child process? sleep(3); // how to kill the two children? } } } return 0;}
管道
- 管道是针对于本地计算机的两个进程之间的通信而设计的通信方法,管道建立后,实际获得两个文件描述符:一个用于读取而另外一个用于写入。
- 最常见的IPC机制,通过pipe系统调用。
- 管道是单工的,数据只能向一个方向流动,需要双向通信时,需要建立起两个管道。
- 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
- 通过打开两个管道来创建一个双向的管道
- 管道是阻塞性的,当进程从管道中读取数据,若没有数据进程会阻塞。
- 当一个进程往管道中不断地写入数据但是没有进程去读取数据,此时只要管道没有满是可以的,但若管道放满数据的则会报错。
匿名管道
- 在关系进程中进行(父进程和子进程、兄弟进程之间)
- 由pipe系统调用,管道由父进程建立。
- 管道位于内核空间,其实是一块缓存。
- int pipe(int fd[2]);
- 功能:创建匿名管道pipe
- 返回: 成功返回0 ,出错返回-1
- fd[0]: 为pipe的读端,用于读取管道;fd[1]: 为pipe的写端,用于写入管道
案例:
int main(){ //匿名管道,第一步:定义一个整型的长度为2的数组 int fd[2] = { }; if(pipe(fd)){ perror("管道创建失败\n"); exit(-1); } int pid = fork(); if(pid == 0){//子进程 -- 读消息 close(fd[1]); while(1){ printf("子进程正在等待消息...\n"); char buffer[1024] = " "; read(fd[0],buffer,1024) ; printf("读取到%s\n",buffer); if(strcmp(buffer,"end") == 0) break; } close(fd[0]); }else if(pid > 0){//父进程 -- 写消息 close(fd[0]); while(1){ char buffer[1024] = " "; printf("请输入你要发送的内容\n"); scanf("%s",buffer); write(fd[1],buffer,strlen(buffer)); if(strcmp(buffer,"end") == 0) break; } wait(NULL); }else{ perror("进程创建失败\n"); exit(-1); } return 0;}
命名管道
- 两个没有任何关系的进程之间通信可通过命名管道进行数据传输,本质是内核中的一块缓存,另在文件系统中以一个特殊的设备文件(管道文件)存在。
- 只要对FIFO有适当访问权限,FIFO可用在任何两个没有任何关系的进程之间通信。
- 本质是内核中的一块缓存,另在文件系统中以一个特殊的设备文件(管道文件)存在。
- 在文件系统中只有一个索引块存放文件的路径,没有数据块,所有数据存放在内核中。
- 命名管道必须读和写同时打开,否则单独读或者单独写会引发阻塞。
- 对FIFO的操作与操作普通文件一样,一般的文件I/O函数都可用于FIFO。
- 通过系统调用mkfifo创建
- int mkfifo(const char * pathname, mode_t mode);
- 功能:创建命名管道
- 返回:若成功则返回0 ,出错返回-1
案例:
int main(){ if(access("pipe",F_OK)){ if(mkfifo("pipe",0664)){ perror("创建管道文件失败\n"); exit(-1); } } int fd = open("pipe",O_RDWR); if(fd < 0){ perror("打开文件失败\n"); exit(-1); } while(1){ char buffer[1024] = " "; printf("请输入内容\n"); fgets(buffer,1024,stdin); write(fd,buffer,strlen(buffer)); if(strcmp(buffer,"end") == 0) break; } close(fd); return 0;}int main(){ if(access("pipe",F_OK)){ if(mkfifo("pipe",0664)){ perror("创建管道文件失败\n"); exit(-1); } } int fd = open("pipe",O_RDWR); if(fd < 0){ perror("打开文件失败\n"); exit(-1); } while(1){ char buffer[1024] = " "; read(fd,buffer,1024); printf("%s\n",buffer); if(strcmp(buffer,"end") == 0) break; } close(fd); return 0;}
popen管道
- The popen() function opens a process by creating a pipe, forking, and invoking the shell.
- FILE *popen(const char *cmdstring, const char *type);
- 返回值: 成功返回文件指针,出错返回NULL
- int pclose(FILE *fp);
- 返回值: cmdstring 的终止状态,出错返回-1
案例:
int main(){ // FILE *popen(const char *command, const char *type); // command:执行的shell命令 // type:打开方式。只能是 "r",或者"w"其他都会报错 // 本质上:创建一个管道,执行command命令,并将执行的结果保存到管道里面。 FILE* fp = popen("ls","r"); if(fp == NULL){ perror("创建管道失败\n"); exit(-1); } while(1){ char buffer[1024] = " "; if(fgets(buffer,1024,fp) == NULL) break; printf("%s",buffer); } printf("\n"); pclose(fp); return 0;}
消息队列
共享内存
信号量
阅读全文
0 0
- Linux进程间通信
- Linux进程间通信
- Linux进程间通信
- Linux进程间通信
- linux 进程间通信
- linux 进程间通信
- Linux进程间通信
- Linux进程间通信
- 【Linux】 进程间通信
- linux进程间通信
- Linux 进程间通信
- Linux进程间通信
- Linux进程间通信
- Linux 进程间通信
- linux间进程通信
- Linux进程间通信
- linux 进程间通信
- Linux进程间通信
- js基本简介
- java中有关面向对象的基本概念
- Codeforces 835D Round #427 D-Palindromic characteristics—— DP+回文串
- 线段树基础
- cronExpression表达式解释:
- Linux 进程间通信
- 剑指offer--二叉树的深度
- JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨
- 数据结构实验之二叉树七:叶子问题
- 【dfs】poj 1020 Anniversary Cake
- 矩阵分析与应用(四)——逆矩阵、广义逆矩阵和Moore-Penrose逆矩阵
- Java设计模式:工厂方法模式(Factory Method Pattern)
- 一个想法照进现实-《IT连》创业项目:一个转折一个反思
- xml读取辅助类