无名管道在文件系统中无文件名称
在文件IO中创建一个文件或打开一个文件是由open函数来实现的,它不能创建管道文件。只能用pipe函数来创建无名管道。
函数形式:
int pipe(int fd[2])
功能:创建无名管道
参数:两个文件描述符。
返回值:成功是0,出错是-1;
注意:
Ø 管道中的东西,读完了就删除了;队列
Ø 如果管道中没有东西可读,则会读阻塞(进程睡眠)。
pipe函数的使用例子:
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd[2];
int ret;
ret = pipe(fd);
if(ret < 0){
printf("creat pipe faliure.\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
return 0;
}
执行结果:
CLC@Embed_Learn:~/linux_io/02/02$ ./a.out
creat pipe sucess fd[0]=3,fd[1]=4
在无名管道中写入与读取数据:
fd[0]和fd[1],管道有一个读端fd[0]用来读和一个写端fd[1]用来写,这个规定不能变。
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd[2];
int ret;
char write_buf[] = "hello linux.";
char read_buf[128];
ret = pipe(fd);
if(ret < 0){
printf("creat pipe faliure.\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
write(fd[1],write_buf,sizeof(write_buf));
read(fd[0],read_buf,128);
printf("read_buf = %s\n",read_buf);
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果:
CLC@Embed_Learn:~/linux_io/02/02/two$ gcc pipe_wr.c
CLC@Embed_Learn:~/linux_io/02/02/two$ ./a.out
creat pipe sucess fd[0]=3,fd[1]=4
read_buf = hello linux.
验证读阻塞
如果管道中没有东西可读,则会读阻塞(进程睡眠)。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{
int fd[2];
int ret;
char write_buf[] = "hello linux.";
char read_buf[128];
ret = pipe(fd);
if(ret < 0){
printf("creat pipe faliure.\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
write(fd[1],write_buf,sizeof(write_buf));
read(fd[0],read_buf,128);
//fist read
printf("read_buf = %s\n",read_buf);
//seconde read
memset(read_buf,0,128);//将read_buf里的内容清空
printf("second read_buf = %s\n",read_buf);
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果:管道中的东西,读完就删除。第二次读的时候read_buf已经被清除了。
实现两个进程通信的例子:
要想两个进程进行通信,在建立同一个管道,所以要在建立进程之前建立管道。
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;//pid_t是一个short类型变量,用它来表示进程id类型,实际上表示的是内核中的进程表的索引。
int ret;
int fd[2];
char process_inter = 0;
ret = pipe(fd);//在建立进程前建立管道,是只建立一个,若在进程之后则不是
if(ret < 0){
printf("crate pipe faiure.\n");
return -1;
}
printf("create pipe is success.\n");
pid = fork();
if(pid == 0){//child process code
int i=0;
read(fd[0],&process_inter,1);
while(process_inter == 0);
for(i=0;i<5;i++){
printf("This is child process i=%d\n",i);
usleep(100);
}
}
if(pid > 0){
int i=0;
for(i=0;i<5;i++){
printf("This is parent process i=%d\n",i);
usleep(100);
}
// sleep(5);
process_inter = 1;
write(fd[1],&process_inter,1);
}
while(1);//等待子进程执行
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果:
CLC@Embed_Learn:~/linux_io/02/02/three$ vi fork.c
CLC@Embed_Learn:~/linux_io/02/02/three$ gcc fork.c
CLC@Embed_Learn:~/linux_io/02/02/three$ ./a.out
create pipe is success.
This is parent process i=0
This is parent process i=1
This is parent process i=2
This is parent process i=3
This is parent process i=4
This is child process i=0
This is child process i=1
This is child process i=2
This is child process i=3
This is child process i=4
无名管道的缺点:不能进行非父子进程关系的通信,若要对没有血缘关系的进程进行通信,需要用有名管道进行通信。