文件到插座适配器蟒蛇 [英] File to socket adapter in python

查看:138
本文介绍了文件到插座适配器蟒蛇的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 ASYNCIO 库在Windows上读取文件一样对象(如 sys.stdin 串口)。

I want to use the asyncio library on Windows to read file-like objects (such as sys.stdin and serial ports).

然而, ASYNCIO 在Windows上的预计可读的对象是插座

However, asyncio on Windows expects readable objects to be sockets.

是否有可能写一个适配器类来包装一个类文件对象与插座的API,这样我可以使用标准输入和串行端口与 ASYNCIO

Is it possible to write an adapter class to wrap a file-like object with the API of a socket so that I could use stdin and serial ports with asyncio?

如果有,请你能不能举一个例子,因为我以前从未使用过的插座?

If so, please could you give an example because I've never used sockets before?

推荐答案

没有,也许是的。

您不能只是换一个类文件对象作为一个插座,反之亦然,并期望它的工作。 ASYNCIO 使用系统引擎盖下调用来执行它的异步魔术和标准输入标准输入从系统的角度来看没有母校你有多少包裹。当使用默认的 SelectorEventLoop 它使用的选择式的系统调用。在Windows上使用 选择 系统调用,它确实的不可以支持什么,但插座。

You can't just wrap a file-like object as a socket, or vice-versa, and expect it to work. asyncio is using system calls under the hood to do its async magic and stdin is stdin from the system's point of view no mater how much you wrap it. When using the default SelectorEventLoop it uses one of the select-like system calls. On Windows it uses the select system call, which does not support anything but sockets.

因此​​,选择吮吸窗口。难道还有其他选择吗?是。在Windows中,只有Windows中,做名为 IOCP(I / O完成端口)异步操作的另一个API。这是一个通知上,完成了输入多路复用器,而不是在选择根据通知 - 当就绪输入多路复用器。该API比做要复杂得多一个简单的选择一个文件电话,但幸运的是 ASYNCIO 拥有的部分的支持它了。

So, select sucks on windows. Is there another option? Yes. On Windows, and only Windows, there is another API for doing async operations called IOCP (I/O Completion Ports). It's a "notify-on-completion" type multiplexer as opposed to the select based "notify-when-ready" type multiplexers. The API is much more complicated than doing a simple select call on a file, but fortunately asyncio has some support for it already.

ProactorEventLoop 在Windows上使用IOCP,它理论上支持从标准输入读书。我没有访问到Windows机器,所以我不能对此进行测试,但给这个一去:

The ProactorEventLoop uses IOCP on Windows and it should theoretically supports reading from stdin. I don't have access to a Windows machine so I can't test this, but give this a go:

# vim: filetype=python3 tabstop=2 expandtab

import asyncio as aio
import os
import sys

if os.name == "nt":
  proactor_loop = aio.ProactorEventLoop()
  aio.set_event_loop(proactor_loop)

@aio.coroutine
def main(loop):
  stdin_reader = aio.StreamReader()
  stdin_transport, stdin_protocol = yield from loop.connect_read_pipe(
    lambda: aio.StreamReaderProtocol(stdin_reader),
    sys.stdin
  )

  line = yield from stdin_reader.read()
  print(line.strip().decode("utf-8"))

  stdin_transport.close()

loop = aio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()

和在Windows上运行的这种等价的:

And run the equivalent of this on Windows:

$ echo blha blha blha | python test.py
blha blha blha

如果一切正常,那么至少你可以做异步标准输入在Windows上。然后你可以尝试类似的东西为标准输出/标准错误或甚至串行端口。

If this works, then at least you can do async stdin on Windows. And then you could try something similar for stdout/stderr or perhaps even serial ports.

如果一切都失败了,你总是可以通过使用 loop.run_in_executor 协程在包装线程阻塞调用模拟异步行为:

If all else fails, you could always simulate async behaviour by wrapping blocking calls in threads using the loop.run_in_executor coroutine:

yield from loop.run_in_executor(None, sys.stdin.readline)

这篇关于文件到插座适配器蟒蛇的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆