原有的代码是爬虫,化简完代码是这样
import asyncio
import aiohttp
async def worker():
    while 1:
        try:
            async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=5)) as session:
                async with session.post('https://www.baidu.com') as r:
                    _ = await r.text()
        except RuntimeError:
            break
async def main():
    await asyncio.wait([worker() for _ in range(100)])
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
只需要不到 100 个协程,cpu 单核就可以 100%,是我对于协程有错误的理解吗,求指点
|      1xiaolinjia      2020-06-29 19:32:27 +08:00 你这不是 100 个。是 100 x while 循环的次数个。 | 
|      2arrow8899      2020-06-29 19:43:08 +08:00 不是你这么用的。。。 | 
|  |      3j0hnj      2020-06-29 19:52:38 +08:00  1 百度要被你干死了…… | 
|  |      4just1 OP | 
|      514v45mJPBYJW8dT7      2020-06-29 20:02:47 +08:00 ```import asyncio import aiohttp async def worker(url): try: async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=5)) as session: async with session.post(url) as r: _ = await r.text() except RuntimeError: break async def main(): urls = ["https://baidu.com", "https://baidu.com"] await asyncio.wait([worker(url) for url in range(urls)]) if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()``` | 
|  |      7just1 OP @rimutuyuan 实际工作的脚本应该是从 queue 获得目标 url,这里简化写成了死循环而已 | 
|  |      8crella      2020-06-29 21:39:42 +08:00  1 如果你要爬取得网站网速快的话,那么平均每两次下载的时间间隔很小,而代码中又是 100 个 worker(),那么可以认为每两次下载时间没有空闲时间,cpu 的单核占用就是达到了 100% | 
|  |      9just1 OP @crella #8 大概可能是这个情况,但是我的疑惑在于 http 会这么消耗 cpu 吗?运行时网络不过是大概 send340kb/s,recv900kb/s (不过小包比较多) 如果这样好像除了堆机器、开多进程,是不是没有办法优化了? | 
|      10silencefly      2020-06-29 22:22:43 +08:00 via iPhone 如一楼的意思 是 100 个 job 一起跑 不是一个 job 跑 100 次 | 
|  |      11just1 OP @silencefly #10 就是 100 个 job 一起所以引入协程,不然一个个太慢了 | 
|  |      12tolerance      2020-06-29 22:59:09 +08:00 求教,写爬虫怎么才能不违法 | 
|  |      14imn1      2020-06-29 23:22:49 +08:00 如果用的是板载网卡,是需要 CPU 处理数据的 用那种死贵的独立网卡,可以卡内处理数据,省点 CPU | 
|  |      15msg7086      2020-06-30 03:30:05 +08:00  1 这也不是 HTTP 啊,这明明是 HTTPS 啊,初始化 TLS 秘钥交换多次握手不要钱的啊…… | 
|      17lpts007      2020-06-30 09:47:37 +08:00 @just1 你知道 while 1 的意思吗  死循环内异步 单核满载不是意料之中吗,跟 http 协议有什么关系? 再说你实际业务生产待爬 url 的速度 也不可能就是 while 1 吧。 注意点别人网站的承受能力,别一不小心搞成攻击了。 | 
|  |      18BingoXuan      2020-06-30 10:04:03 +08:00  2 https 需要消耗一定 cpu 资源去加解密的,而且你写的是 100x 的死循环请求。假如你一秒单线程能完成 10 次,那么实际就是 1000 次请求了。 你需要去掉 while 循环,通过 asyncio 创建 size 为 100 的 queue,不断从 queue 中获取任务,通过 futures 来设置 result 或者 error | 
|  |      19yzk66880      2020-06-30 18:09:49 +08:00 你这 while 1 。。。 | 
|      21yucongo      2020-07-02 11:12:33 +08:00 网上有个 limited_as_completed ( asyncioplus )包,或许适应你要做的。limited_as_completed 的原始作者试过建议将 limited_as_completed 作为 asyncio 的内置标准函数,但好像不成功。 |