简体   繁体   English

Python multiprocessing.managers.BaseManager依次运行已注册的可调用函数

[英]Python multiprocessing.managers.BaseManager running registered callable function sequentially

I am working with a remote manager provided by Python's multiprocessing library. 我正在使用Python的多处理库提供的远程管理器。 I have setup a remote server using BaseManager, to which multiple clients connect simultaneously. 我已经使用BaseManager设置了一个远程服务器,多个客户端同时连接到该服务器。 Unfortunately, my server is serving requests sequentially for each client. 不幸的是,我的服务器正在按顺序为每个客户端提供请求。 My server is supposed to make a network call to Google's directions API to return distance and time. 我的服务器应该通过网络调用Google的Directions API来返回距离和时间。

My understanding was that a new thread would be spawned for each client that connects, so i would not face this problem. 我的理解是,将为每个连接的客户端生成一个新线程,因此我不会遇到此问题。

I have provided a sample of my code in a simplified manner. 我以简化的方式提供了代码示例。

Here is the server code: 这是服务器代码:

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

Here is the client code: 这是客户端代码:

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

Even though the client sends all three requests immediately, the server prints the following: 即使客户端立即发送所有三个请求,服务器也会打印以下内容:

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

Ideally, all started prints should come together. 理想情况下,所有开始的打印件都应该放在一起。 This is a major bottleneck for my application. 这是我的应用程序的主要瓶颈。

the callable you're register ing is a 'creation' method and these are always run in a locked context , but the object it returns is automatically proxied and any methods invoked on it aren't automatically locked 您正在register的可调用对象是“创建”方法,它们始终在锁定的上下文中运行 ,但是它返回的对象将自动被代理,并且对其调用的任何方法都不会被自动锁定

in your demo code, I'd change: 在您的演示代码中,我将更改:

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

to be: 成为:

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

and then use this as: 然后将其用作:

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)

which should allow everything go in parallel. 这应该允许一切并行进行。 I've not actually tested this, but will if you say this doesn't work... 我没有实际测试过,但是如果您说这行不通的话...

not that it matters here, but I generally feel it's better to register these sorts of things in a separate/derived Manager 并不是说这里很重要,但我通常认为最好将这些内容注册在单独的/派生的Manager

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Python多处理管理器(BaseManager / SyncManager)与远程计算机共享队列时断管 - Broken Pipe when Using Python Multiprocessing Managers (BaseManager/SyncManager) to Share Queue with Remote Machines python multiprocessing BaseManager注册类在Ctrl-C后立即失去连接 - python multiprocessing BaseManager registered class lost connection immediately after Ctrl-C Python,使用远程管理器和多处理 - Python, Using Remote Managers and Multiprocessing 停止 Python 多处理 BaseManager 'serve_forever' 服务器? - Stopping a Python Multiprocessing BaseManager 'serve_forever' server? 无法跨多个进程使用多处理 BaseManager 服务器向/从已注册的共享 object 写入/读取值 - Unable to write/read value to/from registered shared object with multiprocessing BaseManager server across multiple processes Python - 队列,管理器和多处理的奇怪行为 - Python - weird behavior with Queues, Managers and Multiprocessing Python多处理:进程对象不可调用 - Python multiprocessing: Process object not callable Python:带有池的多处理“无法调用” - Python: “int not callable” with multiprocessing with pool Python Pandas在多处理管理器之间共享DataFrames - Python Pandas shared DataFrames across Multiprocessing Managers 具有上下文管理器和属性的 Python 多处理管理器 - Python multiprocessing managers with context manager and properties
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM