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()

基本的に、イベント ループは JSON 要求のために 12345 の zmq ポートをリッスンし、利用可能な場合はファイルからコンテンツを読み取ります (利用可能な場合は、それを操作して書き込みます。基本的に、ファイルは構築された特別な /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 ソケットにも当てはまります。

現状では、some_file 参照がガベージ コレクションされると、ファイルの内容がフラッシュされます。

追加:

新しいバージョンの Python が open() で提供するコンテキスト マネージャー ロジックを使用します。

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

このコンテキストが終了するとすぐに、 some_file は自動的にフラッシュされて閉じられます。

于 2013-02-20T16:48:44.853 に答える