需求是这样子的:一个程序要提供一个IPC接口,接收异步的命令。这个接口应该尽量简单,能像/proc
下的文件那样通过写入数据来通信,所以我选中了命名管道。读取命名管道很简单,像普通文件那样打开然后读取就可以了。但这样做的问题是,在没有写者的时候open
会阻塞。man 2 open
下找到了两个标志位:O_ASYNC
和O_NONBLOCK
。我被排在前面的O_ASYNC
骗了,它只是读写时使用信号进行异步操作,open
依旧阻塞。继续向后翻,才看到O_NONBLOCK
,还特意注明了Neither the open() nor any subsequent operations on the file descriptor which is returned will cause the calling process to wait.
试了试,发现open
并不像读写时那样在将阻塞时返回EWOULDBLOCK
错误,而是返回了一个可用的文件描述符。既然文件描述符都有了,接下来自然毫无悬念地select
了。完整的演示代码如下:
#!/usr/bin/env python3 # vim:fileencoding=utf-8 import os import time import select fd = os.open('test', os.O_NONBLOCK | os.O_RDONLY) while True: if not select.select([fd], [], [], 1)[0]: print('waiting...') else: got = os.read(fd, 1024).decode().rstrip() if not got: os.close(fd) fd = os.open('test', os.O_NONBLOCK | os.O_RDONLY) else: print('got', got)