Лучший способ обновить значение из параллельного запуска скрипта - Python - PullRequest
2 голосов
/ 23 декабря 2019

У меня есть два скрипта Python (предположим, script_1 и script_2 ). Script_1 сканирует сеть с использованием subprocess для вызова некоторых подпрограмм и обновляет определенные значения. Скорость его обновления низкая. Он также может бесконечно работать в своем собственном процессе, в отличие от вызова. Script_2 имеет основной цикл, который выполняет ряд различных действий, и некоторые действий зависят от последнего состояния значений, обновленных script_1 . Вот как это не должно быть сделано:

### script_1 ###
from time import sleep
import random

# This could also be an infinitely running
# independent task, updating a file/database/whatever
def tedious_task():
    sleep(10)    # working hard...
    value = random.random() * 10
    return value

### script_2 ###
from script_1 import tedious_task
from time import sleep

while True:
    value = tedious_task()  # waiting...
    if value > 5:
        print("Do something")
    else:
        print("Do something else")

    print("Do other stuff")
    sleep(1)

В качестве примечания, мне не нужно регистрировать обновленные значения script_1 . Мне просто нужно последнее значение.

Я имею в виду несколько различных способов его реализации, таких как прерывания / обратные вызовы, асинхронность, многопоточность, многопоточность или даже запись во внешние местоположения, такие как файлы, базы данных. и т. д. Однако большинство из них являются излишними, а остальные просто не идеальны.

Потоковая обработка - потенциальный кандидат. Мне удобно использовать потоки, однако я много читал о том, как она может дестабилизировать систему, если она не реализована правильно, и мне нужно, чтобы эта система была стабильной в течение длительного времени. «Используйте асинхронный ввод-вывод, когда можете; используйте многопоточность, когда это необходимо», я где-то читал.

Асинхронный ввод-вывод чувствует себя немного излишним (не так сильно, как при использовании базы данных), но я могу ошибаться. Я не использовал асинхронные задачи в течение многих лет (и никогда в Python), поэтому я забыл большинство из них. Моя главная проблема заключается в том, что, поскольку мне нужно только последнее возвращенное значение, если моя основная подпрограмма по какой-то причине замедляется, это приведет к запаздывающей серии возвратов асинхронной функции. Я могу что-то упустить.

Итак, есть ли способ, которым это предпочтительно сделать? Это может звучать как вопрос, основанный на мнении, однако мне действительно нужен ответ, основанный на фактах.

1 Ответ

1 голос
/ 23 декабря 2019

Для многопроцессорной обработки должно работать что-то вроде следующего

from multiprocessing import Process, Value
from time import sleep
import random

def producer(v):
    while True:
        sleep(10)    # working hard...
        with v.get_lock():
            v.value = random.random() * 10

def worker(v):
    while True:
        value = v.value
        if value > 5:
            print("Do something")
        else:
            print("Do something else")
        print("Do other stuff")


if __name__ == '__main__':
    v = Value('i', 7)  # See the docs for multiprocessing.Value
    producer_process = Process(target=producer, args=(v,))
    worker_process = Process(target=worker, args=(v,))
    producer_process.start()
    worker_process.start()
...