【问题标题】:Async generator with next带有下一个的异步生成器
【发布时间】:2018-03-26 22:07:49
【问题描述】:

我有以下代码:

def is_it_bad(word):
    try:
        res = next((item for item in all_names if str(word) in str(item["name"])))
    except:
        res = {'name':word, 'gender':2}
return res

看起来它正在阻止我正在调用 is_it_bad 的异步函数。我对异步不是很熟悉,有什么办法可以让这个函数不阻塞?

函数调用is_it_bad

async def get_genders_by_dict(res):
    letters = re.compile('[^a-zA-Z\ ]')
    fname = unidecode(str(letters.sub('', res['full_name'])).lower())
    fname = letters.sub('', res['username']).lower() + ' ' + fname + ' ' + fname.replace(' ', '')
    fname = fname.split(' ')    
    genders = []
    for j in fname:
        if len(j) > 2:
            print(j)
            genders.append(is_it_bad_tst('_' + j + '_')['gender'])
            for k in genders:
                if int(k) != 2:
                    gender = k
                    print('GOOD: ', '_' + j + '_', gender)


async def get_genders_by_dict_main(loop):
    tasks = [get_genders_by_dict(res) for res in results]
    await asyncio.gather(*tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(get_genders_by_dict_main(loop))

【问题讨论】:

  • 能否请您添加调用is_it_bad函数的部分代码。
  • @SumitJha 抱歉,已添加
  • 你用的是什么python版本?什么是all_names(是不是大序列)?
  • @fabiocerqueira python 3.6.4 all_names = [{'gender': 0.0, 'name': 'aaralyn'}, {'gender': 1.0, 'name' : 'aaric'}] 它有大约 20 000 个项目

标签: python python-asyncio


【解决方案1】:

让这个函数非阻塞?

asyncio 的上下文中,阻塞函数是一个花费大量时间等待网络相关操作(当您从 Web 请求某些内容时)的函数,或者是一个花费大量 CPU 时间(长时间计算)的函数。

通常您可以使用asyncio 同时运行与网络相关的操作,这样可以更快地获得结果。 asyncio 无法以某种方式加速与 CPU 相关的操作,除非在 executor(进程池)中运行它们以获得多核的好处。然而,后者可以使用纯ProcessPoolExecutor 来实现,而根本不需要asyncio

据我所知,您的代码没有描述的情况:get_genders_by_dict 与网络无关,而且它似乎不包含可以在多个内核上并行化的长时间运行的计算。 详细解释请阅读this answer

长话短说,如果我没有遗漏一些你根本不需要的东西asyncio,那么使用它是没有意义的。只需将 get_genders_by_dict 设为普通函数并使用它即可。

【讨论】:

    【解决方案2】:

    我从您的代码中看到的是您正在执行 CPU 有界调用并且它可能会阻塞反应器(循环),我认为解决您的问题的更好方法是使用多处理或仅使用包装器在执行者(另一个进程)

    https://docs.python.org/3/library/asyncio-eventloop.html#executor

    https://docs.python.org/3/library/concurrent.futures.html#processpoolexecutor

    【讨论】:

    • 我已经尝试过使用 ThreadPoolExecutor - 与普通 for 循环相比,时间没有差异。我相信我需要一个异步生成器函数来替换当前的 is_it_bad
    猜你喜欢
    • 2020-11-28
    • 2019-11-16
    • 2015-01-16
    • 2017-03-17
    • 1970-01-01
    • 2016-07-19
    • 2021-06-07
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多