美文网首页
linux无名管道

linux无名管道

作者: 嵌入式工作 | 来源:发表于2018-11-07 15:02 被阅读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);
    

    相关文章

      网友评论

          本文标题:linux无名管道

          本文链接:https://www.haomeiwen.com/subject/uacvxqtx.html