linux无名管道
2018-11-07 本文已影响0人
嵌入式工作
1管道(无名管道)介绍
int pipe(int fd[2]); //成功返回0,失败返回-1;
pipefd[0]元素的描述符为管道读端,
只能用来读;pipe[1]元素的描述符为管道写端,只能用来写。
在使用管道时,应该将对自己来说没有的一端关闭close(),然后再使用自己需要的一端read()或write()
2 管道读写规则
当没有数据可读时
- O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
- O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。
当管道满的时候
- O_NONBLOCK disable: write调用阻塞,直到有进程读走数据
- O_NONBLOCK enable:调用返回-1,errno值为EAGAIN
如果所有管道写端对应的文件描述符被关闭,则read返回0
如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE
当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。
3测试代码
#include<sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(void)
{
int pip_fd[2];
pid_t pid;
char buf_r[100];
char *buf_w;
int r_num;
if(pipe(pip_fd)<0)
{
printf("pipe create fail \n");
exit(1);
}
if((pid=fork())==-1)
{
printf("fork fail \n");
exit(1);
}else if(0==pid)//子进程
{
close(pip_fd[0]);
printf("write pip sleep 3 sec *****************************\n");
sleep(3);
if(-1!=write(pip_fd[1],"hello 123",strlen("hello 123")))
{
printf("write hello 123 \n");
}
if(-1!=write(pip_fd[1],"ok get 456",strlen("ok get 456")))
{
printf("write ok get 456 \n");
}
close(pip_fd[1]);
printf("writed *****************************\n");
exit(0);
}else
{
close(pip_fd[1]);
printf("start read====================\n ");
if((r_num=read(pip_fd[0],buf_r,100))>0)
{
printf("read len :%d -%s\n",r_num,buf_r);
}
close(pip_fd[0]);
printf("have readed====================\n ");
exit(0);
}
}
4非阻塞方式
当管道中的数据被读取后,管道为空。一个随后的read()调用将默认的被阻塞,等待某些数据写入。
若需要设置为非阻塞,则可做如下设置:
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
fcntl(filedes[1], F_SETFL, O_NONBLOCK);