2012-02-13 10 views
13

私はPythonでノンブロッキングメソッドを使ってファイルに書きたいと思っています。いくつかのグーグルでは、言語がfcntlをサポートしていることが判明しましたが、同じ方法を実装する方法はあまり明確ではありません。非ブロック化IOを使用してファイルに書き込む方法は?

これは、コードスニペット(私が間違っているつもりですどこ私は知らない)です:

import os, fcntl 
nf = fcntl.fcntl(0,fcntl.F_UNCLK) 
fcntl.fcntl(0,fcntl.F_SETFL , nf | os.O_NONBLOCK) 
nf = open ("test.txt", 'a') 
nf.write (" sample text \n") 

は、このファイルには、非ブロッキングIO操作を実行するための正しい方法は何ですか?疑わしい。また、私がそうすることを可能にする他のモジュールをPythonで提案できますか?

+0

の可能複製(http://stackoverflow.com/questions/319132/asynchronous-file-writing-possible-in-python) – jcollado

+0

[Pythonで可能書き込み非同期ファイル?]いいえ、私は単純なfcntlを使用してそれを保つ必要があります:) – Rahul

答えて

14

これは、UNIXでのファイルのために非ブロックモードオンにする方法です:UNIXでは

fd = os.open("filename", os.O_CREAT | os.O_WRONLY | os.O_NONBLOCK) 
os.write(fd, "data") 
os.close(fd) 

、しかし、turning on non-blocking mode has no visible effect for regular filesを!ファイルが非ブロックモードであっても、os.writeコールはすぐには戻らず、書き込みが完了するまでスリープします。あなたはos.write呼び出しは数秒かかりますことに気づくでしょう

import os 
import datetime 

data = "\n".join("testing\n" * 10 for x in xrange(10000000)) 
print("Size of data is %d bytes" % len(data)) 

print("open at %s" % str(datetime.datetime.now())) 
fd = os.open("filename", os.O_CREAT | os.O_WRONLY | os.O_NONBLOCK) 
print("write at %s" % str(datetime.datetime.now())) 
os.write(fd, data) 
print("close at %s" % str(datetime.datetime.now())) 
os.close(fd) 
print("end at %s" % str(datetime.datetime.now())) 

:実験的に自分自身にそれを証明するために、これを試してみてください。コールが非ブロッキング(技術的にはブロックしていない、スリープ状態)であっても、ではなく、非同期です。


AFAIKでは、LinuxまたはWindows上でファイルに非同期で書き込む方法はありません。ただし、スレッドを使用してシミュレーションすることはできます。 Twistedには、この目的のためにdeferToThreadという名前のメソッドがあります。ここでは、それを使用する方法は次のとおりです。

from twisted.internet import threads, reactor 

data = "\n".join("testing\n" * 10 for x in xrange(10000000)) 
print("Size of data is %d bytes" % len(data)) 

def blocking_write(): 
    print("Starting blocking_write") 
    f = open("testing", "w") 
    f.write(data) 
    f.close() 
    print("End of blocking_write") 

def test_callback(): 
    print("Running test_callback, just for kicks") 

d = threads.deferToThread(blocking_code) 
reactor.callWhenRunning(cc) 
reactor.run() 
+0

LineReciverやその他のサーバ・ファクトリで構築されたプロトコルの中から、どのように原子炉オブジェクトにアクセスできますか? – Sean

+0

ノンブロッキング書き込みは、POSIX AIOまたはWindows IOCPを使用する通常のファイルに対して実行できます。 – strcat

4

書き込みはOSによってキャッシュされ、数秒後にディスクにダンプされます。つまり、彼らはすでに「ブロックしていません」。特別なことを行う必要はありません。

+0

ファイルが実際にネットワーク共有にマウントされている場合はどうなりますか?確かに、通話は確認応答が受信された後にのみ戻るでしょうか? – Flimm

+1

実装されているリモートファイルシステムとセマンティックの依存、同期または非同期。両方の例、あるいは「近い時に同期」のようなものもあります。 – jcea

関連する問題