2012-02-13 33 views
13

我想在Python中使用非阻塞方法写入文件。在一些Google上,我发现语言支持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 2012-02-13 12:08:26

+0

[异步文件中写的Python可能吗?]没有它没有,我需要通过使用fcntl来保持简单:) – Rahul 2012-02-13 14:19:00

回答

14

这是你如何把无阻塞上的UNIX文件方式:

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

在UNIX,但是,turning on non-blocking mode has no visible effect for regular files!即使文件处于非阻塞模式,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())) 

你会发现os.write调用不会需要几秒钟。即使呼叫是非阻塞的(技术上,它没有阻塞,它正在睡眠),呼叫是而不是异步。


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或服务器工厂构建的其他此类协议中访问reactor对象? – Sean 2013-01-11 22:41:04

+0

使用POSIX AIO或Windows IOCP可以对普通文件进行非阻塞式写入。 – strcat 2014-05-23 08:34:41

4

写操作由操作系统缓存并在几秒钟后转储到磁盘。也就是说,他们已经“不挡”了。你不必做任何特别的事情。

+0

如果文件实际上安装在网络共享上,该怎么办?当然,电话会在收到确认后才会返回? – Flimm 2012-11-29 20:34:26

+1

取决于远程文件系统和语义实现,同步或异步。有两个例子,甚至像“同步关闭”。 – jcea 2012-11-30 01:24:37