python – 3.4.2中的asyncio问题 – 它只是因某种原因终止
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 3.4.2中的asyncio问题 – 它只是因某种原因终止,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4124字,纯文字阅读大概需要6分钟。
内容图文
![python – 3.4.2中的asyncio问题 – 它只是因某种原因终止](/upload/InfoBanner/zyjiaocheng/809/95c70b906886428cacbdd9c07bd91d9f.jpg)
python的新手,花了很多时间阅读文档和其他代码我似乎无法在Python 3中获得新的asyncio模块.
它一直没有堆栈跟踪终止给我一个线索,应该永远运行但不会.
我试图模仿的基本流程概念如下:
从港口读取:
开放端口 – >读取数据(可变长度) – >放在队列1上
然后处理数据:
从queue1获取数据 – >条件适用 – >结果放在队列2上
然后写入端口:
从queue2获取数据并写入端口
永远地从顶部循环
注意:in端口上的数据是零星的,可变长度,并且几个块可能会从’sequence’到达,因此我使用asyncio.我知道asyncio将允许块到达的情况,然后是我的应用程序响应之前的另一个 – 即调用get_io_from_port()有助于协同例程的多次执行.这就是我使用队列来确保不阻塞process_queue()的原因
到目前为止我的玩具示例代码:
import queue
import asyncio
@asyncio.coroutine
def process_queue(q1, q2):
tmp = q1.Get()
if tmp == 'ABCDEF':
q2.put('12345')
elif tmp == 'GHIJKL':
q2.put =('67890')
else:
print('There is a data error')
@asyncio.coroutine
def put_io_to_port(writer, q2):
if not q2.empty():
try:
writer.write(q2.get())
except IOError as e:
print('OUT Port issue: ', e)
@asyncio.coroutine
def get_io_from_port(reader, q1):
try:
data_i = yield from reader.read(1200)
q1.put(data_i)
except IOError as e:
print('IN Port issue: ', e)
def main():
q1 = queue()
q2 = queue()
loop = asyncio.get_event_loop() # main loop declaration
reader, writer = yield from asyncio.open_connection('192.168.1.103', 5555)
# high-level call open streams - read and write
print('Start')
tasks = [
asyncio.async(get_io_from_port(reader,q1)),
asyncio.async(process_queue(q1, q2)),
asyncio.async(put_io_to_port(writer, q2)),] # do these tasks - in this order
loop.run_forever(tasks) # loop through on main loop forever
loop.close()
if __name__ == '__main__':
main()
另外,作为一个旁边 – 如何调试此代码 – 即跟踪?可以提出哪些技巧?我正在使用Eclipse和PyDev,但无济于事.
解决方法:
你在这里犯了几个错误.首先,你将main看作是一个正常的函数,但是你已经在那里放置了一个yield,它会自动将它转换成一个生成器.这意味着当你这样做
if __name__ == "__main__":
main()
main实际上并未执行;对main()的调用只会创建一个立即丢弃的生成器对象(因为你没有将它赋给变量).这就是为什么你很难调试 – main中的代码都没有执行.您应该将main转换为协程并使用loop.run_until_complete来调用它.
接下来,您尝试使用队列模块,该模块并非设计用于单线程异步程序.一旦你调用queue.get(),它就会阻塞你的主线程,这意味着你的asyncio事件循环将被阻止,这意味着你的整个程序将会死锁.您应该使用coroutine-safe asyncio.Queue代替.
你在put_io_to_port中也有一个竞争条件.如果它不是空的,你只是尝试从q2消耗,但是在process_queue有机会运行并填充队列之前可能执行put_io_to_port.如果您只是从put_io_to_port中删除了if not q2.empty()检查,那么看起来你会没事的.
最后,您使用asyncio.async将协程添加到事件循环中,这很好.但是你有一个评论说#按顺序执行这些任务,但这不是程序在asyncio.async中的行为方式.它只是将所有协同程序添加到事件循环中,它们都将并行运行.如果你真的希望它们按顺序运行,你应该这样做:
yield from get_io_from_port(reader,q1)
yield from process_queue(q1, q2)
yield from put_io_to_port(writer, q2)
但这里真的没有必要.您可以同时运行所有这些并获得正确的行为;如果一个协程在另一个协程之前执行,它将等待它所依赖的协程传递它所需的数据,然后继续执行.
你也有一些拼写错误(q1.Get(),q2.put =(…)等).
所以,把所有这些修复放在一起,你得到这个:
import queue
import asyncio
@asyncio.coroutine
def process_queue(q1, q2):
while True:
tmp = yield from q1.get()
if tmp == 'ABCDEF':
yield from q2.put('12345')
elif tmp == 'GHIJKL':
yield from q2.put('67890')
else:
print('There is a data error')
@asyncio.coroutine
def put_io_to_port(writer, q2):
while True:
try:
data = yield from q2.get()
writer.write(data)
except IOError as e:
print('OUT Port issue: ', e)
@asyncio.coroutine
def get_io_from_port(reader, q1):
while True:
try:
data_i = yield from reader.read(1200)
yield from q1.put(data_i)
except IOError as e:
print('IN Port issue: ', e)
@asyncio.coroutine
def main():
q1 = asyncio.Queue()
q2 = asyncio.Queue()
reader, writer = yield from asyncio.open_connection('192.168.1.103', 5555)
# high-level call open streams - read and write
print('Start')
tasks = [
asyncio.async(get_io_from_port(reader,q1)),
asyncio.async(process_queue(q1, q2)),
asyncio.async(put_io_to_port(writer, q2)),]
if __name__ == '__main__':
loop = asyncio.get_event_loop() # main loop declaration
loop.run_until_complete(main())
内容总结
以上是互联网集市为您收集整理的python – 3.4.2中的asyncio问题 – 它只是因某种原因终止全部内容,希望文章能够帮你解决python – 3.4.2中的asyncio问题 – 它只是因某种原因终止所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。