大佬们 我这协程写的有毛病吗?

2020-01-19 14:39:27 +08:00
 Ritter

想用 Python 做一个后台扫描工具
仿照 asyncio 官网的生产者消费者模式写了一个 demo
发现运行到一半会阻塞住(有时会,有时不会?)
但我看着貌似不会卡住啊
求大佬救救孩子

6920 次点击
所在节点    Python
55 条回复
Ritter
2020-01-19 15:34:23 +08:00
@chenqh 大佬 我打印了一下 貌似是在 self.q.get()这卡住了
Ritter
2020-01-19 15:35:36 +08:00
@youngce 请求库是 aiohttp 异步的 意思是 读取文件那里卡住了吗
Ritter
2020-01-19 15:36:08 +08:00
@ipwx 大佬 asyncio 的队列能跨线程使用吗
Ritter
2020-01-19 15:36:36 +08:00
@chenqh put 这个函数是可以运行完的
chenqh
2020-01-19 15:40:09 +08:00
@Ritter 先把日志打出来呀
chenqh
2020-01-19 15:40:46 +08:00
@Ritter 我怀疑你 put 跑完了,但是 consumer 还是卡在哪里
ipwx
2020-01-19 15:41:01 +08:00
@Ritter run_in_executor 本来就是把一个阻塞函数扔到别的线程里面执行,然后把结果拿出来的。

def fn():
....something to do

await loop.run_in_executor(fn)
freshgoose
2020-01-19 15:44:17 +08:00
看来 py 的协程还是很多坑啊……这么说现阶段还是用 golang 写并发比较好?
Ritter
2020-01-19 15:44:19 +08:00
@chenqh 好像是 但是我后面一句已经把 consumer 取消了
Vegetable
2020-01-19 15:45:12 +08:00
@ipwx #8 并不是无法执行阻塞,只是会阻塞 eventloop 而已。这地方不会卡死。这个方法内部的操作也并不是耗时操作。
Vegetable
2020-01-19 15:47:13 +08:00
你这个程序由于 crawl 是不会主动跳出的,所以当任务执行完毕之后,所有 await queue.get 都会阻塞,等待新的任务入队,是卡在这里吗?
Ritter
2020-01-19 15:49:39 +08:00
@Vegetable
async def run(self):
crawls = [self.crawl(i) for i in range(self.max_concurrency)]
consumer = asyncio.gather(*crawls)
...
# cancel consumer
consumer.cancel()

我这里已经把 consumer 取消了
BBrother
2020-01-19 15:53:09 +08:00
有个库叫做 aiofile,你的文件读取是阻塞的
Ritter
2020-01-19 15:55:24 +08:00
@BBrother 可是 put 函数是可以完整运行完的 这里是运行到一半的时候卡住了
chenqh
2020-01-19 15:55:34 +08:00
@Ritter 我一般不是这么退出的, 我一般是再 producer 那边放入特殊的字符串,比如"__end__",然后 consumer 那边接受处理,自己退出的, 你试一试?
chenqh
2020-01-19 15:56:37 +08:00
@Ritter 你这个就是 consumer 的退出问题,导致的
jyyx
2020-01-19 15:58:53 +08:00
消费者那里抛异常, self.q.task_done 并没有执行
加 try finally 试下
Vegetable
2020-01-19 16:03:01 +08:00
#37 jyyx 说的对,报异常会导致任务消费出问题,join()那里会卡住。
BBrother
2020-01-19 16:06:51 +08:00
@Ritter 你的卡住是指程序运行到一半不动了,并且没有输出,也没有执行完,而且还是概率触发?
Ritter
2020-01-19 16:15:23 +08:00
@chenqh https://asyncio.readthedocs.io/en/latest/producer_consumer.html 官网第一个例子应该是你说的这种处理方式 我之前试过貌似也会卡住

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/639162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX