学习笔记-进程间通信(Interprocess communication,IPC) --概念、 pipe and FIFOs
2010-06-03 20:15
281 查看
面试时一再地被问到进程间通信的情况,而我的理解一直停留在概念上和名词上,必须要做点实验加深理解。
一、概述
由于网上资料和各种书籍关于IPC的讲述有少许区别或完整性不够,所以要先选择要查阅的资料,这里我主要基于书《APUE》和《UNIX网络编程第二卷进程间通信》学习IPC。
《UNIX网络编程第二卷进程间通信》中主要叙述4种不同形式的IPC:
1.消息传递(管道、FIFO、消息队列)
2.同步(互斥锁、条件变量、读写锁、文件与记录锁、信号量(semaphore)
3.共享内存区(匿名共享内存区、有名共享内存区)
4.远程过程调用(Solaris门、Sun RPC)
该书讲它不讨论通过计算机通信网络实现的IPC,而主要讨论不涉及网络的IPC,所以,我认为加上
5.Socket(Unix Domain Socket、TCP/IP Socket)就构成完整的IPC.
(面试时最好回答管道、FIFO、信号量等,而不是消息传递、同步等,因为更多书是按照前者分类IPC)
由于每个进程有各自独立的地址空间,进程间通信就要在地址空间外借助于一些其他的东西,图1.1[1]可以形象说明IPC借助什么进行通信。
![](http://hi.csdn.net/attachment/201006/3/0_12755672988Dx7.gif)
二、pipes和FIFOs
1. pipes(管道) :使用最广泛,具有亲缘关系的进程间才能使用管道进行IPC。创建的pipes存在于内核中。一般情况下,管道是半双工管道(不是全双工,也不是单工),即在某一时刻从一端进从一端出,不能在一端即能进也能出(补:单工的意思是任何时刻只能一端进一端出)。有些系统提供了全双工管道,不过,使用半双工管道基本就可以解决很多问题了。用两个半双工管道就能实现全双工管道的功能。
shell中使用管道举例:ls -a | grep "jun"
自己的程序中使用管道的方法:父进程创建pipe,然后fork子进程,这时父子进程通过pipe进行通信了。
程序中使用管道例子代码:(为了抓住重点,删除了处理错误的代码)
int main()
{
int fd[2]; //管道是一种文件,有read端和write端,要用到两个file descriptor
pipe(fd); //创建管道
pid = fork();
if (pid > 0) { //父进程
close(fd[0]); //fd[0]是read端,fd[1]是write端,这里关闭read端。close()是File I/O的API。
write(fd[1], ”hello pipe/n", 11); //通过write端,写入数据。write()是File I/O的API。
}
else { //子进程
close(fd[1]); //关闭write端
int n = read(fd[0], buf, MAX_SIZE);
write(1, buf, n); //整数1,在我所知道的操作系统的实现中是标准输出的File descriptor
}
exit(0);
}
程序代码中使用管道的套路一般是:pipe;fork;exec*,标准I/O提供了popen和pclose函数整合有关管道的函数,使得可以在自己的程序中用更少的代码实现管道。
2. FIFOs, FIFOs are sometimes called named pipes(有名管道)。FIFOs突破了只能在具有亲缘关系的进程间使用的限制,这通过创建一个FIFO类型的文件实现。FIFO数据流是半双工。
shell中使用FIFO举例:
mkfifo fifo1 //创建名为fifo1的有名管道,使用ls命令可以看到fifo1文件(文件类型字母是p)
cat < fifo1 & //后台运行cat,重定向fifo1为输入
ls –a > fifo1 //ls -a的结果重定向到fifo1,也就是通过fifo1传递数据给cat命令
在Unix/Linux中提供了命令mkfifo用于创建FIFO和unlink或rm删除所创建的FIFO。
程序中使用FIFO例子代码:(一个很简单的server-client程序,没有出错处理)
测试方法,先server &, 然后client。
小结[1]
![](http://hi.csdn.net/attachment/201006/3/0_1275567299JF66.gif)
参考资料
1、《UNIX网络编程第二卷进程间通信》
2、《APUE》
一、概述
由于网上资料和各种书籍关于IPC的讲述有少许区别或完整性不够,所以要先选择要查阅的资料,这里我主要基于书《APUE》和《UNIX网络编程第二卷进程间通信》学习IPC。
《UNIX网络编程第二卷进程间通信》中主要叙述4种不同形式的IPC:
1.消息传递(管道、FIFO、消息队列)
2.同步(互斥锁、条件变量、读写锁、文件与记录锁、信号量(semaphore)
3.共享内存区(匿名共享内存区、有名共享内存区)
4.远程过程调用(Solaris门、Sun RPC)
该书讲它不讨论通过计算机通信网络实现的IPC,而主要讨论不涉及网络的IPC,所以,我认为加上
5.Socket(Unix Domain Socket、TCP/IP Socket)就构成完整的IPC.
(面试时最好回答管道、FIFO、信号量等,而不是消息传递、同步等,因为更多书是按照前者分类IPC)
由于每个进程有各自独立的地址空间,进程间通信就要在地址空间外借助于一些其他的东西,图1.1[1]可以形象说明IPC借助什么进行通信。
![](http://hi.csdn.net/attachment/201006/3/0_12755672988Dx7.gif)
二、pipes和FIFOs
1. pipes(管道) :使用最广泛,具有亲缘关系的进程间才能使用管道进行IPC。创建的pipes存在于内核中。一般情况下,管道是半双工管道(不是全双工,也不是单工),即在某一时刻从一端进从一端出,不能在一端即能进也能出(补:单工的意思是任何时刻只能一端进一端出)。有些系统提供了全双工管道,不过,使用半双工管道基本就可以解决很多问题了。用两个半双工管道就能实现全双工管道的功能。
shell中使用管道举例:ls -a | grep "jun"
自己的程序中使用管道的方法:父进程创建pipe,然后fork子进程,这时父子进程通过pipe进行通信了。
程序中使用管道例子代码:(为了抓住重点,删除了处理错误的代码)
int main()
{
int fd[2]; //管道是一种文件,有read端和write端,要用到两个file descriptor
pipe(fd); //创建管道
pid = fork();
if (pid > 0) { //父进程
close(fd[0]); //fd[0]是read端,fd[1]是write端,这里关闭read端。close()是File I/O的API。
write(fd[1], ”hello pipe/n", 11); //通过write端,写入数据。write()是File I/O的API。
}
else { //子进程
close(fd[1]); //关闭write端
int n = read(fd[0], buf, MAX_SIZE);
write(1, buf, n); //整数1,在我所知道的操作系统的实现中是标准输出的File descriptor
}
exit(0);
}
程序代码中使用管道的套路一般是:pipe;fork;exec*,标准I/O提供了popen和pclose函数整合有关管道的函数,使得可以在自己的程序中用更少的代码实现管道。
2. FIFOs, FIFOs are sometimes called named pipes(有名管道)。FIFOs突破了只能在具有亲缘关系的进程间使用的限制,这通过创建一个FIFO类型的文件实现。FIFO数据流是半双工。
shell中使用FIFO举例:
mkfifo fifo1 //创建名为fifo1的有名管道,使用ls命令可以看到fifo1文件(文件类型字母是p)
cat < fifo1 & //后台运行cat,重定向fifo1为输入
ls –a > fifo1 //ls -a的结果重定向到fifo1,也就是通过fifo1传递数据给cat命令
在Unix/Linux中提供了命令mkfifo用于创建FIFO和unlink或rm删除所创建的FIFO。
程序中使用FIFO例子代码:(一个很简单的server-client程序,没有出错处理)
server.c |
#define FIFO "fifo" #define FILE_MODE (S_IRUSR | S_IWUSR) int main() { int readfd, n; char buf[1024]; mkfifo(FIFO, FILE_MODE); //创建FIFO,即在文件系统中建一个文件 readfd = open(FIFO, O_RDONLY); //既然是个文件,就能用open while ((n = read(readfd, buf, 1024)) > 0) { buf = '/0'; printf("server:%s/n", buf); } return 0; } |
client.c |
#define FIFO "fifo" //FIFO的名字就是文件名 #define FILE_MODE (S_IRUSR | S_IWUSR) int main() { int writefd; int n; char buf[1024]; writefd = open(FIFO, O_WRONLY); //先运行服务器,FIFO已经存在 while ((n = read(0, buf, 1024)) > 0) { buf[n-1] = '/0'; printf("%s/n", buf); n = write(writefd, buf, strlen(buf)); } unlink(FIFO); //删除FIFO return 0; } |
小结[1]
![](http://hi.csdn.net/attachment/201006/3/0_1275567299JF66.gif)
参考资料
1、《UNIX网络编程第二卷进程间通信》
2、《APUE》
相关文章推荐
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
- Linux进程间通信IPC学习笔记之同步一(线程、互斥锁和条件变量)
- Linux进程间通信IPC学习笔记之管道
- Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
- 学习笔记-PPP and PPPoE基本概念
- Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
- Linux进程间通信IPC学习笔记
- Linux进程间通信IPC学习笔记之有名管道
- [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之一 基本概念
- Linux进程间通信——IPC共享内存学习笔记
- Linux进程间通信IPC学习笔记之消息队列(Posix)
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
- 《APUE》Chapter 4 Files and directories (学习笔记加上自己的代码)
- java学习笔记(7)基本概念之IO
- (笔记)Linux内核学习(六)之并发和同步概念
- 数据结构学习笔记--基本概念
- Android 学习笔记之AndBase框架学习(六) PullToRefrech 下拉刷新的实现
- Hadoop学习笔记(1):概念和整体架构
- HCNA-Cloud学习笔记 ----云计算的概念
- Hadoop学习笔记(1):概念和整体架构