Python:检查命名管道是否包含数据 [英] Python: Check if named pipe has data

查看:286
本文介绍了Python:检查命名管道是否包含数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Unix系统上有一个始终在运行的Python3进程,并且我希望能够通过命名管道从其他仅偶尔运行的进程中向其随机发送数据.如果命名管道没有数据,我希望我的进程继续做其他事情,因此我需要检查它是否有数据无阻塞.

I have a Python3 process on my Unix system always running, and I want to be able to randomly send data to it through a named pipe from other processes that only run occasionally. If the named pipe doesn't have data, I want my process to continue doing other things, so I need to check whether it has data without blocking.

我不知道如何在不打开它的情况下进行检查,但是除非我设置了非阻塞标志,否则打开块.而且,如果我设置了该标志,那么如果我在读取之前或读取期间向管道写入数据,则会崩溃.

I can't figure out how to check without opening it, but opening blocks unless I set the non-blocking flag. And if I set the flag, it crashes if I happen to write to the pipe before or during the read.

这是我设法做到的最好的事情:

This is the best I've managed to do:

import os

fifo = "pipe_test.fifo"
done = False
fd = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK)
while not done:
    try:
        s = os.read(fd, 1024) # buffer size may need tweaking
        print(s)
        done = True
    except BlockingIOError as e:
        pass
os.close(fd)

如果管道中没有数据,我得到b"",它退出.如果管道中有数据,则它会获得一次异常,然后重试,然后获取数据.好像我做错了事,可能会遇到奇怪的比赛条件.有更好的方法吗?

If there's no data in the pipe, I get b"", and it exits. If there's data in the pipe, it gets an exception once, retries, then gets the data. Seems like I'm doing something wrong and might run into weird race conditions. Is there a nicer way to do this?

推荐答案

如果您可以更改客户端代码,则不会使用命名管道,但是

I would not use a named-pipe if you can change the clients' code, but UNIX domain sockets instead, because they support datagrams:

import errno, fcntl, os, socket

服务器:

# bind socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind('pipe_test.fifo')
# set socket non-blocking
fcntl.fcntl(sock.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

# get a datagram
try:
    datagram = sock.recv(1024)
except (OSError, socket.error) as ex:
    if ex.errno not in (errno.EINTR, errno.EAGAIN):
        raise
else:
    print('Datagram: %r' % datagram)

客户:

sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.sendto('Hello!', 'pipe_test.fifo')

但是您可能想研究 multithreading 而不是使用非阻塞插座.

But you might want to look into multithreading instead of using non-blocking sockets.

这篇关于Python:检查命名管道是否包含数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆