如何设置管道为非阻塞

        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;
}

结果如下:

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

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Unix/Linux系统中,管道(pipe)是内核提供的一种半连接通信机制,它允许进程间通过文件描述符(file descriptor, fd)进行数据交换。当管道的fd设置阻塞阻塞模式,会影响到读写操作的行为。 **阻塞模式(Blocking):** 当fd设置阻塞模式时,如果试图从管道读取数据但管道为空(没有数据),或者向管道写入数据但管道已满,操作系统会将调用该操作的线程挂起,直到有数据可读或空间可用。阻塞模式保证了数据的一致性,适合于处理顺序执行、不需要立即响应的情况。 **阻塞模式(Non-blocking):** 在阻塞模式下,同样的操作会立即返回,如果管道没有数据或空间,操作系统不会阻塞,而是直接返回错误,如`EAGAIN`(资源暂时不可用)。这使得进程能够更高效地处理并发,因为线程不会因等待IO而阻塞其他操作,适用于事件驱动或高并发场景,但需要程序自行管理IO状态和错误检查。 设置阻塞阻塞的主要差别在于性能、可扩展性和应用程序的复杂性: 1. **性能**:阻塞模式通常更快,因为它减少了不必要的线程阻塞,提高了系统的吞吐量。 2. **并发能力**:阻塞模式支持高并发,因为多个线程可以同时尝试进行I/O操作,而阻塞可能导致线程竞争同一资源。 3. **代码复杂性**:阻塞模式需要更多的错误检查和同步逻辑,否则可能会导致数据丢失或死锁。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值