【Linux】管道实现进程间通信
2018-03-22 20:29
531 查看
一. 进程间通信(IPC)
我们知道进程之间都是相互独立的,任何一个进程的全局变量在另一个进程中是看不到的,如果进程之间需要交换数据就要通过内核。进程间通信(InterProcess Communication)的本质就是让两个进程看到共同的资源。进程间通信的目的
数据传输:一个进程需要将它的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源
通知事件:一个进程需要向另一个进程发送消息,通知其发生了某种事情(比如进程终止父进程告诉子进程)
进程控制:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,能够及时知道它的状态改变。
进程间通信的分类
管道:匿名管道,命名管道
System V IPC:消息队列,共享内存,信号量
POSIX IPC:消息队列,共享内存,信号量,互斥量,读写锁,条件变量
二. 管道(pipe)
我们把一个进程连接到另一个进程的一个数据流称之为管道,是Unix中最古老的进程间通信形式。我们可以分为匿名管道和命名管道。1. 匿名管道
特点:只能用于具有血缘关系的进程之间通信
生命周期随进程,进程退出,管道释放
管道是半双工的,数据只能从一个方向传输
管道是基于字节流的
管道是自带同步机制的,在保证数据安全的前提下,按照特定顺序访问临界资源
函数原型
#include <unisted> int pipe(int fd[2]);
功能:创建一个匿名管道
参数:fd文件描述符数组,其中fd[0]表示读,fd[1]表示写
返回值:成功返回0,失败返回错误代码
例子
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> int main() { int fd[2]={0}; if(pipe(fd)==-1) { perror("pipe"); return 1; } pid_t pid; pid=fork(); if(pid==-1) { perror("fork"); return 2; } if(pid==0) { //child close(fd[0]); int a=5; char *buf="Hello, I am your child"; while(a--) { write(fd[1], buf, strlen(buf)); sleep(1); } } else { //Parent close(fd[1]); while(1) { char buf[1024]={0}; ssize_t s = read(fd[0], buf, sizeof(buf)-1); buf[s]=0; if(s>0) { printf("Parent: %s\n", buf); } else if(s==0) { printf("quit\n"); break; }else { perror("read"); return 3; } } } return 0; }
如果写端的文件描述符关闭,那么读端一直读到文件结尾返回0;
如果写端的文件描述符没有关闭并且写端不写数据,那么读端读完一直等待;
如果写端一直写数据,读端不读,那么写端写满一直等待直到开始读数据;
如果写端一直写数据,读端不读并且关闭文件描述符,那么系统会结束掉写的进程。
2.命名管道
特点:命名管道是一种特殊类型的文件
命名管道可以用于不具有血缘关系的进程
除此之外与匿名管道基本相似
函数原型
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
功能:创建命名管道
参数:pathname表示管道文件路径,mode表示文件权限
返回值:成功返回0,失败返回-1,错误原因存于errno中
例子
client.c
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #include<string.h> int main() { int fd = open("mypipe", O_WRONLY); if(fd < 0) { perror("open"); return 1; } char buf[1024] = {0}; while(1) { printf("Please Enter # "); fflush(stdout); ssize_t s = read(0, buf, sizeof(buf)-1); if(s > 0) { buf[s] = 0; write(fd, buf, strlen(buf)); } else if(s == 0) { printf("read finish"); return 0; } else { perror("read"); return 2; } } close(fd); return 0; }
server.c
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> int main() { umask(0); if(mkfifo("mypipe", 0644) < 0) { perror("mkfifo"); return 1; } int b607 fd = open("mypipe", O_RDONLY); if(fd < 0) { perror("open"); return 2; } char buf[1024] = {0}; while(1) { printf("Please wait...\n"); ssize_t s = read(fd, buf, sizeof(buf)-1); if(s < 0) { perror("read"); return 3; } else if(s == 0) { printf("client is quit\n"); return 0; } else { buf[s-1] = 0;//为了去掉输入时的换行符,所以才s-1 printf("client says # %s\n", buf); } } close(fd); return 0; }
相关文章推荐
- 命名管道实现进程间通信--石头、剪刀、布游戏 分类: linux 2014-06-01 22:50 467人阅读 评论(0) 收藏
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux进程间通信---有名管道 代码实现
- Linux 上实现双向进程间通信管道
- linux中使用匿名管道实现进程间通信
- Linux 上实现双向进程间通信管道
- 【Linux】管道--实现进程间通信
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- Linux上实现双向进程间通信管道(socketpair)
- Linux 上实现双向进程间通信管道
- Linux 上实现双向进程间通信管道
- linux 管道实现进程间通信
- Linux编程练习 --进程间通信2--两个管道实现双向通信