27

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

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

我是否遗漏了什么,或者仅仅是在异步编程中扭曲的主要用途是用于网络,而对于其他文件描述符操作还没有真正解决,而不是担心非阻塞 IO 的纯度?

4

5 回答 5

14

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

于 2010-03-15T21:08:59.043 回答
3

在 Twisted - #3983中有一张公开的票。

于 2010-03-30T21:16:37.897 回答
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'])
于 2015-11-14T13:32:07.173 回答
2

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

截至 2017 年 5 月,获得扭曲的异步磁盘 io 的唯一合理方法是将同步 io 调用包装在deferToThread.

于 2017-06-04T15:21:41.463 回答
-8

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

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

如果您担心其他问题,请澄清您的问题。

于 2009-11-12T08:54:17.923 回答