异步生成器与下一个

时间:2018-03-26 12:30:05

标签: python python-asyncio

我有以下代码:

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))

2 个答案:

答案 0 :(得分:2)

  

使此功能无阻塞?

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

通常,您可以使用asyncio同时运行与网络相关的操作,以便更快地获得结果。 asyncio除了在executor(进程池)中运行它们之外,不能以某种方式加速与CPU相关的操作,以获得多个核心的好处。然而,后者可以使用纯ProcessPoolExecutor来实现,而根本没有asyncio

据我所知,您的代码不是所描述的情况:get_genders_by_dict与网络无关,它似乎不包含可在多个核心上并行化的长时间运行的计算。  请阅读this answer以获取详细说明。

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

答案 1 :(得分:0)

我从你的代码中看到的是你正在进行CPU有界调用并且它可以阻止反应器(循环),我认为解决问题的更好方法是使用多处理或只使用包装器来运行任务执行者(另一个过程)

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

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