本文来自依云's Blog,转载请注明。
需求是这样子的:一个程序要提供一个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)
Oct 19, 2011 02:01:07 PM
也可以起线程。
Oct 19, 2011 04:25:25 PM
我就喜欢异步,不喜欢多线程 :-)
Oct 20, 2011 03:09:25 PM
其实IPC通信里面共享内存,和消息队列是最常用到的
Oct 20, 2011 04:08:56 PM
对那些不熟。shell 里怎么调用?
Oct 20, 2011 09:11:52 PM
共享内存/消息队列貌似都过时了吧。。。。。
不过Linux都有替代的实时库扩展。。3.01 KERNEL貌似又多了个消息队列的扩展实现。。
我不熟悉,随便说说。。。。
顺便踩依云头两脚。
Oct 21, 2011 10:01:52 PM
其实,为什么不用UNIX域套接字?和网络编程几乎相同。不过accept还是会阻塞。
Oct 21, 2011 10:07:16 PM
因为 shell 操作起来比较复杂。另一个原因是我对套接字编程已经相当熟悉了,但基本没怎么用过命名管道。
Nov 02, 2011 05:14:48 PM
shell里面我还没有用过!只是在程序中使用
Nov 29, 2011 11:24:07 AM
用 asyncore 模块就可以了吧,mkfifo 后打开,然后就是直接主循环