Ответ 1
Вот как вы включаете неблокирующий режим для файла в 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
занимает несколько секунд. Хотя вызов не блокируется (технически, он не блокирует, он спал), вызов не является асинхронным.
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()