Python 如何使用非阻塞IO写入文件?
我想在Python中使用非阻塞方法写入文件。在一些谷歌搜索中,我发现该语言支持Python 如何使用非阻塞IO写入文件?,python,file-io,nonblocking,Python,File Io,Nonblocking,我想在Python中使用非阻塞方法写入文件。在一些谷歌搜索中,我发现该语言支持fcntl,但实现该语言的方法对我来说不是很清楚 这是代码片段(我不知道哪里出了问题): 这是对文件执行非阻塞IO操作的正确方法吗?我对此表示怀疑。另外,您能推荐Python中允许我这样做的其他模块吗?写操作由操作系统缓存,几秒钟后转储到磁盘。也就是说,他们已经“不阻塞”。您无需执行任何特殊操作。这是在UNIX中打开文件非阻塞模式的方法: fd = os.open("filename", os.O_CREAT | os
fcntl
,但实现该语言的方法对我来说不是很清楚
这是代码片段(我不知道哪里出了问题):
这是对文件执行非阻塞IO操作的正确方法吗?我对此表示怀疑。另外,您能推荐Python中允许我这样做的其他模块吗?写操作由操作系统缓存,几秒钟后转储到磁盘。也就是说,他们已经“不阻塞”。您无需执行任何特殊操作。这是在UNIX中打开文件非阻塞模式的方法:
fd = os.open("filename", os.O_CREAT | os.O_WRONLY | os.O_NONBLOCK)
os.write(fd, "data")
os.close(fd)
但是,在UNIX上!即使文件处于非阻塞模式,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()
可能重复的不是,我需要通过使用fcntl:)保持它的简单性,如果该文件实际上装载在网络共享上呢?当然,调用只有在收到确认后才会返回?这取决于远程文件系统和实现的语义(同步或异步)。两者都有,甚至“关闭时同步”之类的例子。如何从LineReciver或服务器工厂构建的其他此类协议中访问reactor对象?可以使用POSIX AIO或Windows IOCP对常规文件进行非阻塞写入。
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()