【问题标题】:Tornado PipeIOStream: OSError: [Errno 9] Bad file descriptorTornado PipeIOStream: OSError: [Errno 9] 错误的文件描述符
【发布时间】:2018-06-01 09:33:15
【问题描述】:

我有一个小型微网络服务,它存储由 ID 标识的本地消息。为了确保不会同时写入文件,我实现了一个队列。下面的代码只工作一次,第二次文件上传会在下面抛出回溯,我真的不知道如何正确处理 fd。

from tornado import web, ioloop, gen
from tornado.queues import Queue
from tornado.iostream import PipeIOStream

class Sample:
    def __init__(self):
        self.queue = Queue()

    @gen.coroutine
    def write_queue(self):
        while True:
            item = yield self.queue.get()
            print("Message with id %s stored" % item[0])
            fd = open(item[0], 'ab')
            stream = PipeIOStream(fd.fileno())
            yield stream.write(item[1])
            stream.close_fd()

class MainHandler(web.RequestHandler):

    def initialize(self, store):
        self.store = store

    @gen.coroutine
    def put(self, id):
        yield self.store.queue.put((id, self.request.body))


def start(store):
    return web.Application([
        (r"/(.*)", MainHandler,
         {"store": store})
    ])

if __name__ == '__main__':
    store = Store()
    app = start(store)
    app.listen(8888)
    ioloop.IOLoop.current().add_callback(store.write_queue)
    ioloop.IOLoop.current().start()




ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0x7f46657f46a8>, <Future finished exception=OSError(9, 'Bad file descriptor')>)
Traceback (most recent call last):

    stream = PipeIOStream(fd.fileno())
  File "/usr/local/lib/python3.5/dist-packages/tornado/iostream.py", line 1643, in __init__
    self._fio = io.FileIO(self.fd, "r+")
OSError: [Errno 9] Bad file descriptor

【问题讨论】:

    标签: python tornado


    【解决方案1】:
    1. open 返回的文件描述符不是管道。在PipeIOStream 中使用常规文件通常是合法的,但在 linux 上它没有有用。这样的文件描述符总是被认为是可读的,并且从它们读取或写入它们总是阻塞。所以像这样使用 PipeIOStream 并不比简单地做fd.write(item[1]) 更好。

    2. 您已经以只写模式打开了文件,但 PipeIOStream 将其文件包装在一个读/写包装器中(实际上我有点惊讶这能正常工作,因为真正的管道是单向的) .我认为这就是这个异常的来源。如果您以'ab+' 模式打开文件,我认为它会起作用。不过,我还没有尝试过。

    【讨论】:

    • 1.据我所知,使用队列来编写序列化无论如何都会阻塞,我将不再使用 PipeIOStream ,因为上述示例既无用也无济于事。 2. 'ab+' 也不行。
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2020-08-28
    相关资源
    最近更新 更多