Это безумная реализация типа потребительского типа? - PullRequest
0 голосов
/ 13 сентября 2011
# file1.py

class _Producer(self):

  def __init__(self):
    self.chunksize = 6220800
    with open('/dev/zero') as f:
      self.thing = f.read(self.chunksize)
    self.n = 0
    self.start()

  def start(self):
    import subprocess
    import threading

    def produce():
      self._proc = subprocess.Popen(['producer_proc'], stdout=subprocess.PIPE)
      while True:
        self.thing = self._proc.stdout.read(self.chunksize)
        if len(self.thing) != self.chunksize:
          msg = 'Expected {0} bytes.  Read {1} bytes'.format(self.chunksize, len(self.thing))
          raise Exception(msg)
        self.n += 1

    t = threading.Thread(target=produce)
    t.daemon = True
    t.start()
    self._thread = t

  def stop(self):
    if self._thread.is_alive():
      self._proc.terminate()
      self._thread.join(1)

producer = _Producer()
producer.start()

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

# some_other_file.py
import file1
my_thing = file1.producer.thing 

Несколькодругие потребители могут получить ссылку на file.producer.thing, все они должны использовать с того же producer_procproducer_proc никогда не должен быть заблокирован.Это вменяемая реализация?GIL python делает его потокобезопасным, или мне нужно переопределить, используя Очередь для получения данных рабочего потока?Нужно ли потребителям явно делать копию этой вещи?

Думаю, я пытаюсь реализовать что-то вроде шаблона «Производитель / Потребитель» или «Наблюдатель», но я не совсем понимаю все технические детали шаблонов проектирования.

  • Один производитель постоянно производит вещи
  • Несколько потребителей, использующих вещи в произвольные моменты времени
  • producer.thing должны быть заменены новыми, как только новыйодна из них доступна, большинство вещей останутся неиспользованными, но это нормально
  • Несколько потребителей могут читать одну и ту же вещь или читать одну и ту же вещь дважды подряд.Они только хотят быть уверенными, что получили самую последнюю вещь, когда их об этом попросили, а не какую-то устаревшую вещь.
  • Потребитель должен иметь возможность использовать вещь до тех пор, пока он имеет ее в объеме, даже если производитель уже переписал его self.thing новой новой вещью.

1 Ответ

1 голос
/ 13 сентября 2011

Учитывая ваши (необычные!) Требования, ваша реализация кажется правильной. В частности,

  • Если вы обновляете только один атрибут, Python GIL должно быть достаточно. Однобайтовые инструкции являются атомарными.
  • Если вы делаете что-то более сложное, добавьте блокировку! В любом случае это практически безвредно - если вы заботитесь о производительности или многоядерной масштабируемости, вы, вероятно, не будете использовать Python!
  • В частности, учтите, что self.thing и self.n в этом коде обновляются в виде отдельных инструкций байт-кода. GIL может быть выпущен / получен между ними, поэтому вы не сможете получить согласованное представление о них обоих, если не добавите блокировку. Если вы этого не сделаете, я бы предложил удалить self.n, поскольку это "привлекательная неприятность" (легко неправильно) или, по крайней мере, добавить комментарий / строку документации с этим предупреждением.
  • Потребителям не нужно делать копию. Вы никогда не мутируете с конкретным объектом, на который указывает self.thing (и не можете с строковыми объектами; они неизменяемы), а Python является сборщиком мусора, поэтому до тех пор, пока потребитель получает ссылку на него, он может продолжайте получать к нему доступ, не беспокоясь о том, что делают другие потоки. Худшее, что может случиться, это ваша программа, использующая много памяти из нескольких поколений self.thing, которая поддерживается.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...