学习笔记
pipe函数
用于创建并打开管道
管道有两个口。
#include <unistd.h>
int pipe(int pipefd[2]);
参数1:
pipefd[0] :读端
pipefd[1] :写端
返回值:
成功:0
失败:-1 errno
管道的写端: 是指进程写到管的的端口
管道的读端: 是指进程从管道读取的的端口
管道的读写端个人感觉是站在进程角度来描述。
父进程创建管道的时候,相当于打开一个读端,一个写端
父进程创建子进程的时候,父子进程共享文件描述符。
子进程也有一个读端一个写端
管道是单向流动
父进程要做写操作的,那么父进程要关闭读端
子进程要做读操作的,那么子进程要关闭写端
$cat mypipe.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
int ret;
int fd[2];
pid_t pid;
char *str ="hello pipe\n";
char buf[1024];
ret = pipe(fd);
if(-1 == ret)
{
sys_err("pipe error!");
}
pid = fork();
if(pid > 0)
{
close(fd[0]);
write(fd[1],str,strlen(str));
close(fd[1]);
}
else if(0 == pid)
{
close(fd[1]);
ret = read(fd[0],buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
close(fd[0]);
}
return 0;
}
read 函数的返回值
-1:出错
0: 文件末尾
>0:读到实际字节数
$make mypipe
gcc mypipe.c -o mypipe -Wall -g
$./mypipe
$hello pipe
$
可以发现输出有点奇怪。
不是第一次看见看见了
原因:父进程先于子进程结束。
解决办法:让父进程sleep 几秒钟。
$cat mypipe.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
int ret;
int fd[2];
pid_t pid;
char *str ="hello pipe\n";
char buf[1024];
ret = pipe(fd);
if(-1 == ret)
{
sys_err("pipe error!");
}
pid = fork();
if(pid > 0)
{
close(fd[0]);
write(fd[1],str,strlen(str));
sleep(1);
close(fd[1]);
}
else if(0 == pid)
{
close(fd[1]);
ret = read(fd[0],buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
close(fd[0]);
}
return 0;
}
make mypipe
gcc mypipe.c -o mypipe -Wall -g
$./pipe
bash: ./pipe: No such file or directory
$./mypipe
hello pipe
$