Bootstrap

如何设置管道为非阻塞

        LINUX中,管道的读写两端是阻塞的,例如读端会一直阻塞直到写端写入内容,才会立即返回。其实也可以将管道中的读或写端设置为非阻塞状态。

        如果要设置读端或者写端为非阻塞,参考以下三个步骤:

  •      int flags = fcntl(fd[0], F_GETFL, 0);
  •      flag |= O_NONBLOCK;
  •      fcntl(fd[0], F_SETFL, flags);

        以读端设置为非阻塞为例: 

  • 写端没有关闭,管道中没有数据可读,则read返回-1
  • 写端没有关闭,管道中有数据可读,则read返回实际读到的字节数
  • 写端已经关闭,管道中有数据可读,则read返回实际读到的字节数
  • 写端已经关闭,管道中没有数据可读,则read返回0

   以一个程序为例,验证read的是否返回值如上所罗列     

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
using namespace std;
int main()
{
        //创建管道
        //int pipe(int pipefd[2]);
        int fd[2];
        int ret = pipe(fd);
        if(ret<0)
        {
                perror("pipe error");
                return -1;
        }

        //close(fd[0]);
        //write(fd[1], "hello world", strlen("hello world"));   

        //关闭写端
        close(fd[1]);

        //设置管道的读端为非阻塞
        int flag = fcntl(fd[0], F_GETFL);
        flag |= O_NONBLOCK;
        fcntl(fd[0], F_SETFL, flag);

        char buf[64];
        memset(buf, 0x00, sizeof(buf));
        int n = read(fd[0], buf, sizeof(buf));
        cout << "read over, n==[" << n << "], buf==[" << buf << "]" << endl;

        return 0;
}

执行结果如下:

 验证了上述的第四种情况。

以第三种情况为例:写端已经关闭,管道中有数据可读,则read返回实际读到的字节数

代码如下:

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
using namespace std;
int main()
{
        //创建管道
        //int pipe(int pipefd[2]);
        int fd[2];
        int ret = pipe(fd);
        if(ret<0)
        {
                perror("pipe error");
                return -1;
        }

        //close(fd[0]);
        write(fd[1], "hello world", strlen("hello world"));

        //关闭写端
        close(fd[1]);

        //设置管道的读端为非阻塞
        int flag = fcntl(fd[0], F_GETFL);
        flag |= O_NONBLOCK;
        fcntl(fd[0], F_SETFL, flag);

        char buf[64];
        memset(buf, 0x00, sizeof(buf));
        int n = read(fd[0], buf, sizeof(buf));
        cout << "read over, n==[" << n << "], buf==[" << buf << "]" << endl;

        return 0;
}

结果如下:

 读到了数据,验证成功!!

;