10
14
2011
9

通过命名管道进行异步通信

本文来自依云's Blog,转载请注明。

需求是这样子的:一个程序要提供一个IPC接口,接收异步的命令。这个接口应该尽量简单,能像/proc下的文件那样通过写入数据来通信,所以我选中了命名管道。读取命名管道很简单,像普通文件那样打开然后读取就可以了。但这样做的问题是,在没有写者的时候open会阻塞。man 2 open下找到了两个标志位:O_ASYNCO_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)
Category: Linux | Tags: linux python fifo 异步 | Read Count: 17730
Avatar_small
依云 说:
Oct 19, 2011 04:25:25 PM

我就喜欢异步,不喜欢多线程 :-)

Avatar_small
星空™ 说:
Oct 20, 2011 03:09:25 PM

其实IPC通信里面共享内存,和消息队列是最常用到的

Avatar_small
依云 说:
Oct 20, 2011 04:08:56 PM

对那些不熟。shell 里怎么调用?

星海 说:
Oct 20, 2011 09:11:52 PM

共享内存/消息队列貌似都过时了吧。。。。。

不过Linux都有替代的实时库扩展。。3.01 KERNEL貌似又多了个消息队列的扩展实现。。

我不熟悉,随便说说。。。。
顺便踩依云头两脚。

Mike 说:
Oct 21, 2011 10:01:52 PM

其实,为什么不用UNIX域套接字?和网络编程几乎相同。不过accept还是会阻塞。

Avatar_small
依云 说:
Oct 21, 2011 10:07:16 PM

因为 shell 操作起来比较复杂。另一个原因是我对套接字编程已经相当熟悉了,但基本没怎么用过命名管道。

Avatar_small
星空™ 说:
Nov 02, 2011 05:14:48 PM

shell里面我还没有用过!只是在程序中使用

fanhe 说:
Nov 29, 2011 11:24:07 AM

用 asyncore 模块就可以了吧,mkfifo 后打开,然后就是直接主循环


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com