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

27 投票
6 回答
8386 浏览
提问于 2025-04-15 15:56

我在想,使用twisted进行文件访问时,是否有一个公认的模式。我看过很多例子(比如twisted.python.log、twisted.persisted.dirdbm、twisted.web.static),但它们似乎并不太在意文件访问时是否会阻塞。

我觉得应该有一个明显的接口,可能是从abstract.FileDescriptor继承的,所有的文件访问都应该通过这个接口来进行,作为生产者和消费者。

我是不是漏掉了什么,还是说twisted在异步编程中的主要用途是网络方面,而在其他文件描述符操作上并没有真正搞清楚,不太关注非阻塞IO的纯粹性?

6 个回答

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

在Twisted这个项目中,有一个关于这个问题的公开工单 - #3983

14

我觉得你可能在找 fdesc模块。如果你想了解更多关于Python中非阻塞输入输出的内容,可以看看这个 视频

撰写回答