简体   繁体   English

Python进程等待

[英]Python process wait

I have this application that shares work across multiple devices and starts processes on them, they often need to synchronize to each other.我有这个应用程序可以跨多个设备共享工作并在它们上启动进程,它们通常需要相互同步。

  1. A web app opens an SSH connection to servers. Web 应用程序打开与服务器的 SSH 连接。
  2. It starts n Python instances per server.它为每个服务器启动n 个Python 实例。
  3. Then closes the SSH connection.然后关闭 SSH 连接。

After that the only way each agent will communicate is with MQTT (Publish / subscribe on topics).之后,每个代理通信的唯一方式是使用 MQTT(发布/订阅主题)。 The MQTT library I'm using is Paho-MQTT.我使用的 MQTT 库是 Paho-MQTT。

My current issue is that I can't find a good way to make them wait.我目前的问题是我找不到让他们等待的好方法。 I feel like while true : sleep is not a good way of doing it but I have no clue on how to do it better.我觉得while true : sleep不是一种好的方法,但我不知道如何做得更好。

My current code looks like this:我当前的代码如下所示:

def wake_up(self, client, userdata, message) -> None:
   self.wake_up_token += 1

def wait(self) -> None:
   while self.wake_up_token == 0:
       sleep(self.wait_delay)
   self.wake_up_token -= 1

So far my only idea would be to find the best wait delay by dichotomy tho it will be time consuming so I'm hoping on a better solution.到目前为止,我唯一的想法是通过二分法找到最佳的等待延迟,但这会很耗时,所以我希望有更好的解决方案。

Note:笔记:

def wait():
   while self.wake_up_token == 0:
      pass

is a terrible solution because the process will be constantly in competition to check the condition and it makes the system thousands of times slower.这是一个糟糕的解决方案,因为该过程将不断竞争以检查条件,并且它会使系统慢数千倍。

Minimal example I guess: (1 agent, 1 scheduler)我猜最小的例子:(1个代理,1个调度程序)

from paho.mqtt.client import Client
from time import sleep

class Agent:

    def __init__(self, broker_ip: str, client_id: str):
        self.client: Client = Client(client_id=client_id)
        self.client.username_pw_set(username="something", password="veryverysecured")
        self.client.connect(host=broker_ip)
        self.client.subscribe("wake_up_topic")
        self.client.message_callback_add("wake_up_topic", self.wake_up)
        self.client.loop_start()

        self.wake_up_token = 0
        
    def wake_up(self, client, userdata, message) -> None:
        self.wake_up_token += 1
    
    def wait(self) -> None:
        while self.wake_up_token == 0:
            sleep(self.wait_delay)
        self.wake_up_token -= 1
    
    def run(self):
        while True:
            # do something
            self.client.publish(topic="agent/action_done", message="")
            self.wait()
            # do something

class Scheduler:

    def __init__(self, broker_ip: str):
        self.client: Client = Client(client_id="scheduler")
        self.client.username_pw_set(username="something", password="veryverysecured")
        self.client.connect(host=broker_ip)
        self.client.subscribe("agent/action_done")
        self.client.message_callback_add("agent/action_done", self.wake_up)
        self.client.loop_start()

        self.wake_up_token = 0

    def wake_up(self, client, userdata, message) -> None:
        self.wake_up_token += 1
    
    def wait(self) -> None:
        while self.wake_up_token == 0:
            sleep(self.wait_delay)
        self.wake_up_token -= 1
    
    def run(self):
        while True:

            #agents are doing their thing

            self.wait()
            self.client.publish(topic="wake_up_topic", message="")

I don't know if it is useful, but the goal of the whole project is to build a MAS frameworks that shares the agents across multiple servers.我不知道它是否有用,但整个项目的目标是构建一个跨多个服务器共享代理的MAS框架。

I think a standard Semaphore is most useful in this case.我认为标准信号量在这种情况下最有用。 I can't test this, since I don't have an MQTT client/server running, but it should be something like this:我无法对此进行测试,因为我没有运行 MQTT 客户端/服务器,但它应该是这样的:

import threading

class Scheduler:

    def __init__(self, broker_ip: str):
        # your init code here (unchanged), but add this line:
        self.semaphore = threading.Semaphore(0)

    def wake_up(self, client, userdata, message) -> None:
        self.semaphore.release()
    
    def wait(self) -> None:
        self.semaphore.acquire()

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM