Python - Реализация объекта Future - PullRequest
0 голосов
/ 16 марта 2020

Мне нужен объект Future в python3.

Python имеет две встроенные реализации:

  1. модуль asyncio имеет его, но он не подходит для мое приложение.

  2. concurrent.futures имеет его, но в документации указано, что этот объект должен создаваться только объектами Executor:

Следующие методы Future предназначены для использования в модульных тестах и ​​реализациях Executor.

https://docs.python.org/3/library/concurrent.futures.html#future -объектов

Базовый интерфейс c:

class Future:
   def get(self):
       pass
   def set(self, val):
       pass

Хотя ключ здесь в том, что если get вызывается до set, метод блокируется до установки значения.

set устанавливает значение и освобождает любое поток, ожидающий get.

Безопасно ли использовать одну из встроенных реализаций выше в многопоточном приложении?

Как это эффективно реализовать?

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

Под руководством @SolomonSlow я реализовал этот код:

from threading import Lock, Condition

class Future:
    def __init__(self):
        self.__condition = Condition(Lock())
        self.__val = None
        self.__is_set = False

    def get(self):
        with self.__condition:
            while not self.__is_set:
                self.__condition.wait()
            return self.__val

    def set(self, val):
        with self.__condition:
            if self.__is_set:
                raise RuntimeError("Future has already been set")
            self.__val = val
            self.__is_set = True
            self.__condition.notify_all()

    def done(self):
        return self.__is_set

Любые предложения приветствуются.

0 голосов
/ 16 марта 2020

Как реализовать это эффективно?

Не знаю, насколько эффективно, но просто :

Звучит как класс с value член, is_set член и lock и condition. Метод set() должен

  • заблокировать lock
  • и вызвать ошибку, если is_set уже имеет значение true, или же
    • is_set = True
    • установить значение
    • condition.notifyAll()

Метод get() должен заблокировать блокировку и затем l oop в ожидании условия переменная, пока is_set не станет True, и, наконец, вернет значение.

Если есть более эффективный способ сделать это с чистым кодом Python, это за пределами моего понимания.

...