非阻塞标准输出[C/Linux]

Posted

技术标签:

【中文标题】非阻塞标准输出[C/Linux]【英文标题】:Non blocking stdout[C / Linux] 【发布时间】:2018-08-23 21:56:33 【问题描述】:

我必须编写基于 udp 套接字接收的数据执行操作的程序,并且必须尽可能将数据写入管道(可能是指管道中有足够的空间)。管道阻塞,实际上它是标准输出。

如果没有写作行为,我会写这样的东西:

while(true) 
    if (poll(poll_fd, n, -1) > 0) 
        if (poll_fd[0].revents & POLLIN) 
            poll_fd[0].revents = 0;
            handle_read();
        
        /* handlers for other read descriptors ... */
     else 
        perror("poll");
        exit(1);
    

如何添加程序编写行为?

写轮询只能告诉写一个字节不会阻塞,每次只写一个字节不是很有效。 据我所知,我无法将文件标志设置为非阻塞,因为它会泄漏到从该管道读取的其他程序(它会更改文件描述,而不是文件描述符)。

【问题讨论】:

"Poll on write只能说写一个字节不会阻塞",不,一般可以写很多,如果一个文件准备好写,即使你问写也会返回太多了,看看write的返回就知道你写了多少字节。 @Stargateur 如果管道被阻塞并且我尝试写入它超过可用空间它不会阻塞? ***.com/questions/51994830/… 【参考方案1】:

正如您所指出的,poll() 会告诉您是否至少有一个字节可写入而不会阻塞。管道可能能够接受更多字节,但在执行写入操作之前您无法真正判断。

如果管道设置为非阻塞,write() 将尽可能多地写入字节,并返回实际写入的字节数。

然后你必须跟踪事情,以便下次有机会管道可写。如果您有(比如说)1000 个字节要写入,而写入操作只接受(比如说)250 个字节,那么您必须在缓冲区中提前 250 个字节,并在管道可写时尝试写入剩余的 750 个字节再次。

【讨论】:

以上是关于非阻塞标准输出[C/Linux]的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

C/C++ 服务器,通过标准输入/标准输出与客户端通信(阻塞标准输入,直到读取了多个字节)

golang调用shell命令标准输出阻塞管道

C:从标准输出块中读取