如何使用非阻塞IO写入文件?

时间:2012-02-13 11:04:17

标签: python file-io nonblocking

我想在Python中使用非阻塞方法写入文件。在一些谷歌搜索中,我发现语言支持fcntl以便这样做,但实现相同的方法对我来说不是很清楚。

这是代码片段(我不知道我哪里出错了):

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中建议其他任何允许我这样做的模块?

2 个答案:

答案 0 :(得分:16)

这是在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()

答案 1 :(得分:4)

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