匿名管道
原理
- 内核空间的队列式内存(缓冲区)
- 队列式内存,内核管理同步和互斥,而共享内存和文件通信需要信号量或者锁机制来保证同步互斥
特点
- 半双工
- 进程全部退出后,匿名管道自动释放,所以数据无法保存
- 可以使用read write close,不能用lseek(队列读写)
- 常用与父子进程间通信(匿名管道来进行非亲缘进程间通信需要辅助以文件描述符?)
- 由内核管理的队列读写方式,自带同步互斥功能
API
#include <unistd.h>
int pipe(int pipefd[2]);
参数表:
pipefd[2]:读端和写端的文件描述符
返回值:
0:成功
-1:出错
示例
/*
匿名管道用于fork的父子进程之间
整形数组两个成员分别是读端和写端,对应两个文件描述符
虽然进程可以同时获得读端和写端两个文件描述符,但是,
由于匿名管道应该是半双工的,所以真正使用的时候,
发送方应该先关闭读端描述符,接收方应该关闭写端描述符
如果想全双工通信,应该建立两个匿名管道,如果用一个会发生错乱
pfd[0]对应读,pfd[1]对应写
1. int pfd[2]
2. pipe(pfd)
3. 父write(pfd[1],"123456",7)
子read(pdf[0],buf,7)
*/
//匿名管道用于父子进程间的通信。
//父写子读
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
using namespace std;
int main()
{
char buf[100];
int pfd[2];
if( ( pipe(pfd) ) == -1)
{
perror("pipe");
exit(1);
}
int pid;
if( ( pid=fork() ) == -1)
{
perror("fork");
exit(1);
}
else if(pid == 0)//子进程,读
{
close(pfd[1]);
sleep(1);
read(pfd[0],buf,7);
cout << buf << endl;
close(pfd[0]);
}
else
{
close(pfd[0]);
write(pfd[1],"123456",7);//父进程,写
close(pfd[1]);
wait(NULL);
}
return 0;
}
命名管道
原理
- 内核空间的队列式内存
- 又名(FIFO文件)
特点
- 文件系统可见,有对应的文件节点信息
- 虽然文件系统里有,但是硬盘中没有
- 因为有名称,非亲缘进程可以依靠他通信
- 按照文件操作进行操作(lseek除外)
API
#include <sys/stat.h>
int mkfifo(char *filename,mode_t mode);
参数表:
filename:命名管道名称
mode:使用方式(如0644)
返回值:
0:成功
-1:失败
示例代码
写端
1 #include <sys/stat.h>//mkfifo()
2 #include <sys/types.h>
3 #include <fcntl.h>
4 #include <unistd.h>//sleep(),write(),close()
5
6 int main()
7 {
8 char buf[100];
9 int fd;
10
11
12
13 mkfifo("testpipe",0644);
14 fd = open("testpipe",O_WRONLY);
15 write(fd,"123456",7);
16 close(fd);
17
18 sleep(10);
19 return 0;
20 }
读端
1 #include <sys/stat.h>
2 #include <sys/types.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5
6 #include <iostream>
7 using namespace std;
8
9 int main()
10 {
11 char buf[100];
12 int fd;
13 sleep(1);
14 fd = open("testpipe",O_RDONLY);
15 read(fd,buf,7);
16 cout << buf <<endl;
17
18 close(fd);
19 return 0;
20 }
网友评论