使用Twisted进行非阻塞文件访问

时间:2009-11-12 08:47:11

标签: python twisted

我正在试图弄清楚是否存在使用twisted的文件访问的事实模式。我看过的很多例子(twisted.python.log,twisted.persisted.dirdbm,twisted.web.static)实际上并不担心阻止文件访问。

似乎应该有一些明显的接口,可能继承自abstract.FileDescriptor,所有文件访问都应该作为生产者/消费者进行。

我是否遗漏了某些内容,或者仅仅是异步编程中的扭曲主要用于网络并且它还没有真正用于其他文件描述符操作,而不是担心非阻塞IO的纯度? / p>

5 个答案:

答案 0 :(得分:14)

我认为您正在寻找fdesc module。有关Python中非阻塞I / O的更多信息,您还可以观看此video

答案 1 :(得分:3)

Twisted中有一张打开的门票 - #3983

答案 2 :(得分:2)

经过大量的搜索,试验和错误后,我终于想出了如何使用fdesc

from __future__ import print_function

from twisted.internet.task import react
from twisted.internet import stdio, protocol
from twisted.internet.defer import Deferred
from twisted.internet.fdesc import readFromFD, setNonBlocking


class FileReader(protocol.Protocol):
    def __init__(self, filename):
        self.f = open(filename, 'rb')

    def dataReceived(self, data):
        self.transport.write(data)

    def connectionMade(self):
        fd = self.f.fileno()
        setNonBlocking(fd)
        readFromFD(fd, self.dataReceived)

    def connectionLost(self, reason):
        self.f.close()

def main(reactor, filename):
    stdio.StandardIO(FileReader(filename))

[编辑:我还想出了一种不需要使用协议的简单方法]

def getFile(filename):
    with open(filename) as f:
        d = Deferred()
        fd = f.fileno()
        setNonBlocking(fd)
        readFromFD(fd, d.callback)
        return d


def main(reactor, filename):
    d = getFile(filename)
    return d.addCallback(print)

像这样运行:

react(main, ['/path/to/file'])

答案 3 :(得分:2)

fdesc模块可能对于与套接字或管道异步通信很有用,但是当给出一个引用普通文件系统文件的fd时,它会阻塞io(并通过一个相当奇怪的接口)。对于磁盘io,fdesc实际上是蛇油;不要使用它。

截至2017年5月,将异步磁盘io置于扭曲状态的唯一合理方法是将同步io呼叫包装在deferToThread中。

答案 4 :(得分:-8)

我不确定你想要达到什么目标。当你进行日志记录时,Python将确保(通过全局解释器日志)来自多个线程的日志消息一个接一个地进入文件。

如果您担心阻止IO,那么操作系统会为您的文件添加默认缓冲区(通常为4KB),您可以在open()调用中传递缓冲区大小。

如果您对其他事情感到担忧,请澄清您的问题。