- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 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/
我的问题是关于 multiprocessing.Managers.BaseManager 的正确用法.文档中的主要示例展示了如何通过创建 BaseManager 的子类来自定义此类。如果有人这样做是为
我正在使用 Python 多处理库提供的远程管理器。我使用 BaseManager 设置了一个远程服务器,多个客户端同时连接到该服务器。不幸的是,我的服务器正在按顺序为每个客户端提供请求。我的服务器应
我在 Python 3.6 中针对进程间通信进行了以下设置: from multiprocessing.managers import BaseManager class MyManager(Base
使用 Python 2.7, 我使用派生自 multiprocessing.managers 的管理器跨进程传递许多大对象。 BaseManager 并且我想使用 cPickle 作为序列化程序以节省
在上个月,当我们尝试使用 Python 2.6.x 多处理包在几台不同的 (linux) 计算机之间共享队列时,我们遇到了一个长期存在的问题。我也直接向 Jesse Noller 提出了这个问题,因为
Python 3.8 引入了新的共享内存功能。我们正在尝试使用 SharedMemoryManager 并抛出 NameError。 我认为我们可能在复杂的场景中做错了什么,所以我使用 python
我是一名优秀的程序员,十分优秀!