gpt4 book ai didi

Python multiprocessing.managers.BaseManager 按顺序运行注册的可调用函数

转载 作者:太空宇宙 更新时间:2023-11-03 20:37:30 25 4
gpt4 key购买 nike

我正在使用 Python 多处理库提供的远程管理器。我使用 BaseManager 设置了一个远程服务器,多个客户端同时连接到该服务器。不幸的是,我的服务器正在按顺序为每个客户端提供请求。我的服务器应该对 Google 的路线 API 进行网络调用以返回距离和时间。

我的理解是,将为每个连接的客户端生成一个新线程,因此我不会遇到这个问题。

我以简化的方式提供了代码示例。

这是服务器代码:

import time
from multiprocessing.managers import BaseManager
import threading

class DistanceTime:

def get_distance_time(self):
print('started by thread %s'%(threading.get_ident()))
# assume that network request was made here
time.sleep(2)
print('ended by thread %s'%(threading.get_ident()))

def server():
distance_time=DistanceTime()
BaseManager.register('get_distance_time', callable=distance_time.get_distance_time)
manager = BaseManager(address=('localhost', 5000), authkey=b'abracadabra')
server = manager.get_server()
print('server running')
server.serve_forever()

server()

这是客户端代码:

from multiprocessing.managers import BaseManager
from concurrent.futures import ThreadPoolExecutor
import time

def client():
BaseManager.register('get_distance_time')
manager = BaseManager(address=('localhost', 5000), authkey=b'abracadabra')
manager.connect()
executor = ThreadPoolExecutor(max_workers=3)
# client mades three simultaneous requests to the server
b=executor.submit(manager.get_distance_time)
b=executor.submit(manager.get_distance_time)
c=executor.submit(manager.get_distance_time)
print('done')
time.sleep(5)

client()

即使客户端立即发送所有三个请求,服务器也会打印以下内容:

server running
started by thread 16740
ended by thread 16740
started by thread 4712
ended by thread 4712
started by thread 7132
ended by thread 7132

理想情况下,所有开始的打印应该放在一起。这是我的应用程序的主要瓶颈。

最佳答案

注册的可调用函数是一个“创建”方法,这些是 always run in a locked context ,但它返回的对象会自动被代理,并且在其上调用的任何方法都不会自动锁定

在您的演示代码中,我会更改:

def server():
distance_time=DistanceTime()
BaseManager.register('get_distance_time', callable=distance_time.get_distance_time)

成为:

def server():
distance_time = DistanceTime()
BaseManager.register('DistanceTime', lambda: distance_time)

然后将其用作:

distance_time = manager.DistanceTime()
a = executor.submit(distance_time.get_distance_time)
b = executor.submit(distance_time.get_distance_time)
c = executor.submit(distance_time.get_distance_time)

这应该允许一切并行进行。我还没有实际测试过这个,但如果你说这不起作用的话,我会测试......

这并不重要,但我通常认为最好在单独/派生的 Manager 中注册这些东西

关于Python multiprocessing.managers.BaseManager 按顺序运行注册的可调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57077642/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com