V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dongcheng
V2EX  ›  Python

多进程里嵌套协程,并发数增加的时候,程序卡死是怎么回事?

  •  
  •   dongcheng · 2021-01-27 17:09:56 +08:00 · 2150 次点击
    这是一个创建于 1402 天前的主题,其中的信息可能已经有所发展或是发生改变。
    import multiprocessing
    from multiprocessing import Semaphore
    import time
    import asyncio
    import aiohttp
    import requests
    import random,time, datetime
    import utils
    import json

    def start_loop(turn):

    request_url = 'https://www.baidu.com'

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    tasks = []
    for num in range(2000):

    func = aio_request(request_url,turn,loop)
    task = asyncio.ensure_future(func)
    tasks.append(task)

    try:
    ret = loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    except Exception as e:
    print('loop 中断或者完成',e)

    return turn

    async def aio_request(url,headers,turn,loop):

    async with aiohttp.ClientSession() as s:
    async with await s.get(url) as response:
    print('请求内容', url)
    # response.read()二进制(.content )
    result = await response.json()
    print(url, '获取内容完成')

    def main():

    start = time.time()

    pool = multiprocessing.Pool(processes = 30)
    for turn in range(10):
    pool.apply_async(start_loop, (turn, ))

    pool.close()
    pool.join()
    print('总耗时:',time.time()-start)
    if __name__ == "__main__":
    main()

    这是个简单例子。主要逻辑是,多进程跑协程任务,协程处理并发 2000 个地址以上。奇怪的地方在于,我这个例子也能跑,但放到项目里就卡死。而且并发 20 能跑,2000 就卡死。把这个协程单独运行(非进程内)也可以跑,不知道是不是阻塞了。之前实在没并发编程经验,不知道算不算很低级的错误。。。
    9 条回复    2021-01-28 17:56:54 +08:00
    linw1995
        1
    linw1995  
       2021-01-27 18:49:52 +08:00
    问问题用 gist 展示代码是美德。
    tanranran
        2
    tanranran  
       2021-01-27 18:51:22 +08:00
    问问题用 gist 展示代码是美德。
    linw1995
        3
    linw1995  
       2021-01-27 18:52:40 +08:00
    `async with await s.get(url) as response:` 这行写错了吧,光 async with 就好了
    dongcheng
        4
    dongcheng  
    OP
       2021-01-27 19:01:28 +08:00
    @linw1995 这么写没报错。不过我发现原因貌似在,semaphore = asyncio.Semaphore(10*multiprocessing.cpu_count())
    dongcheng
        5
    dongcheng  
    OP
       2021-01-27 19:02:00 +08:00
    semaphore 这个值好像不能随便填
    LeeReamond
        6
    LeeReamond  
       2021-01-27 19:36:35 +08:00
    问问题用 gist 展示代码是美德。
    qbqbqbqb
        7
    qbqbqbqb  
       2021-01-28 00:14:05 +08:00
    linw1995
        8
    linw1995  
       2021-01-28 12:51:41 +08:00
    @dongcheng 问题的代码里没见到有这个 semaphore 。再说你这个用法也不对
    deplives
        9
    deplives  
       2021-01-28 17:56:54 +08:00
    一个靠缩紧区分代码块的语言你给我一把梭的顶头写,你给谁看呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2203 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 00:20 · PVG 08:20 · LAX 16:20 · JFK 19:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.