3

使用 PyZMQ 的 IOLoop 实例时,我遇到了奇怪的系统行为:

def main():
    context = zmq.Context()
    s = context.socket(zmq.REP)
    s.bind('tcp://*:12345')
    stream = zmqstream.ZMQStream(s)
    stream.on_recv(on_message)

    io_loop = ioloop.IOLoop.instance()
    io_loop.add_handler(some_file.fileno(), on_file_data_ready_read_and_then_write, io_loop.READ)
    io_loop.add_timeout(time.time() + 10, another_handler)
    io_loop.start()

def on_file_data_ready_read_and_then_write(fd, events):
   # Read content of the file and then write back
   some_file.read()
   print "Read content"
   some_file.write("blah")
   print "Wrote content"

def on_message(msg):
   # Do something...
   pass

if __name__=='__main__':
    main()

基本上,事件循环监听 12345 的 zmq 端口以获取 JSON 请求,并在可用时从文件中读取内容(当它这样做时,对其进行操作并回写。基本上,该文件是一个特殊的 /proc/ 内核模块,已构建为了那个原因)。

一切正常,但由于某种原因,在查看 strace 时,我看到以下内容:

...
1. read(\23424) <--- Content read from file
2. write("read content")
3. write("Wrote content")
4. POLLING
5. write(\324324) # <---- THIS is the content that was sent using some_file.write()
...

所以看起来写入文件不是按照 python 脚本的顺序完成的,但是写入该文件的系统调用是在轮询之后完成的,即使它应该在第 2 行和第 3 行之间完成。

有任何想法吗?

4

1 回答 1

1

看起来您遇到了缓存问题。如果 some_file 是类似对象的文件,您可以尝试在其上显式调用 .flush() ,ZMQ Socket 也是如此,它也可以出于效率原因保存消息。

就目前而言,当 some_file 引用被垃圾收集时,文件的内容将被刷新。

额外的:

使用较新版本的 Python 通过 open() 提供的上下文管理器逻辑

with open("my_file") as some_file:
     some_file.write("blah")

一旦完成此上下文, some_file 将自动刷新并关闭。

于 2013-02-20T16:48:44.853 回答