当前位置: 首页 > 面试题库 >

异步与多处理相结合会出现什么样的问题(如果有)?

蒯翰墨
2023-03-14
问题内容

几乎每个人都知道,当他们初次使用Python进行线程处理时,GIL使真正想并行执行处理的人痛苦不堪-至少给了机会。

我目前正在考虑实现类似Reactor模式的东西。实际上,我想在一个类线程上侦听传入的套接字连接,并且当有人尝试连接时,接受该连接并将其传递给另一个类线程进行处理。

我(尚)不确定我可能要面对什么样的负担。我知道目前对传入邮件设置了2MB的上限。从理论上讲,我们每秒可以得到数千个(尽管我不知道实际上是否已经看到过类似的东西)。处理消息所花费的时间并不是
重要,尽管显然更快会更好。

我正在研究Reactor模式,并使用该multiprocessing库(至少在测试中)开发了一个小示例,该示例似乎运行良好。但是,现在/不久我们将拥有可用的asyncio库,该库将为我处理事件循环。

通过组合使用asyncio,有什么可以咬我的multiprocessing吗?


问题答案:

尽管您不应该直接使用,但是您应该能够安全地合并asyncio并且multiprocessing没有太多麻烦multiprocessing。的大罪asyncio(以及基于异步框架的任何其他事件循环)被阻塞事件循环。如果您尝试multiprocessing直接使用,则在任何时候阻止等待子进程时,都将阻止事件循环。显然,这很糟糕。

避免这种情况的最简单方法是用于BaseEventLoop.run_in_executor在中执行函数concurrent.futures.ProcessPoolExecutorProcessPoolExecutor是使用来实现的进程池multiprocessing.Process,但是asyncio内置支持在其中执行功能而不阻塞事件循环的功能。这是一个简单的例子:

import time
import asyncio
from concurrent.futures import ProcessPoolExecutor

def blocking_func(x):
   time.sleep(x) # Pretend this is expensive calculations
   return x * 5

@asyncio.coroutine
def main():
    #pool = multiprocessing.Pool()
    #out = pool.apply(blocking_func, args=(10,)) # This blocks the event loop.
    executor = ProcessPoolExecutor()
    out = yield from loop.run_in_executor(executor, blocking_func, 10)  # This does not
    print(out)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

对于大多数情况,仅此功能就足够了。如果你发现自己需要其他结构的multiprocessing,如QueueEventManager,等,有一个所谓的第三方库aioprocessing(全面披露:我写的),它提供asyncio所有的兼容版本的multiprocessing数据结构。这是一个演示示例:

import time
import asyncio
import aioprocessing
import multiprocessing

def func(queue, event, lock, items):
    with lock:
        event.set()
        for item in items:
            time.sleep(3)
            queue.put(item+5)
    queue.close()

@asyncio.coroutine
def example(queue, event, lock):
    l = [1,2,3,4,5]
    p = aioprocessing.AioProcess(target=func, args=(queue, event, lock, l)) 
    p.start()
    while True:
        result = yield from queue.coro_get()
        if result is None:
            break
        print("Got result {}".format(result))
    yield from p.coro_join()

@asyncio.coroutine
def example2(queue, event, lock):
    yield from event.coro_wait()
    with (yield from lock):
        yield from queue.coro_put(78)
        yield from queue.coro_put(None) # Shut down the worker

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    queue = aioprocessing.AioQueue()
    lock = aioprocessing.AioLock()
    event = aioprocessing.AioEvent()
    tasks = [ 
        asyncio.async(example(queue, event, lock)),
        asyncio.async(example2(queue, event, lock)),
    ]   
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()


 类似资料:
  • Spring Data repository中的查询可以异步执行,参考Spring执行异步方法。这意味着方法可以在被调用时立刻返回,而真正的查询执行会被当做一个任务提交到Spring的TaskExecutor。 @Async Future<User> findByFirstname(String firstname); //1 @Async CompletableFu

  • 本文向大家介绍问题:如果数据有问题,怎么处理;相关面试题,主要包含被问及问题:如果数据有问题,怎么处理;时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 1.上下采样平衡正负样例比;2.考虑缺失值;3.数据归一化 解析:发散问题需要自己展现自己的知识面      

  • 问题内容: 我发现在Python 3.4中,用于多处理/线程的库很少:多处理vs线程与asyncio。 但是我不知道使用哪个,或者是“推荐的”。他们做的是同一件事还是不同?如果是这样,则将哪一个用于什么?我想编写一个在计算机上使用多核的程序。但是我不知道我应该学习哪个图书馆。 问题答案: 它们旨在(略有)不同的目的和/或要求。CPython(典型的主线Python实现)仍然具有全局解释器锁,因此多

  • 我使用JavaScript有这个条件,我有两个文本框,我将在其中比较输入(输入是数字)。条件是当textbox 2小于textbox 1时,它将显示一条警告消息,说明textbox 2必须大于textbox 2。所以当输入是这样的时候 为什么当它将2与9进行比较时,它不会发出任何警报? 以下是我的情况:

  • 嗨,我有Flux,在迭代每个元素时,它会创建新的单声道。我也有其他单声道之外的通量。并要做到以下几点:当流量(与相应的内部单声道的结束),然后做第二个单声道。最大的挑战是单声道内部的流量从网络客户端请求中产生。作为起点,请看看“加载”方法。基本上没有webClient它的工作,但在情况下与webClient内部地图工作之后。使用Spring启动2 渐变依赖性:

  • 它给出了错误:ORA-06550:第9行,第7列:PLS-00103:在期望下列之一时遇到了符号“elsif”: &=-+;in是mod余数而不是rem<>或!=或~=>=<=<>和或类似于2类似于4类似于multiset成员子multiset之间 00000-“行%s,列%s:\n%s”*原因:通常是PL/SQL编译错误。