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

2024-04-26 15:07:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用Python中的非阻塞方法写入一个文件。在一些google上,我发现该语言支持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中允许我这样做的其他模块吗?


Tags: 文件方法代码testimporttxt语言os
2条回答

以下是在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调用确实需要几秒钟。即使调用是非阻塞的(从技术上讲,它不是阻塞的,而是休眠的),调用也是异步的。


不过,在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()

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

相关问题 更多 >