# 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_proc
。永远不应该阻止producer_proc
。这是一个理智的实现吗? python GIL是否使线程安全,或者我是否需要使用Queue重新实现获取工作线程的数据?消费者是否需要明确制作该物品的副本?
我想我正在尝试实现像Producer / Consumer模式或Observer模式这样的东西,但我并不清楚设计模式的所有技术细节。
producer.thing
一旦新的可用,就应该换成新鲜的东西,大多数东西都会被闲置但是没关系self.thing
。 答案 0 :(得分:1)
鉴于您的(不寻常!)要求,您的实施似乎是正确的。特别是,
self.thing
和self.n
会在单独的字节码指令中更新。 GIL可以在两者之间发布/获取,因此除非添加锁定,否则无法获得两者的一致视图。如果您不打算这样做,我建议删除self.n
,因为这是一个“有吸引力的滋扰”(容易被误用)或者至少在此警告中添加评论/文档字符串。self.thing
指向的特定对象(并且不能使用字符串对象;它们是不可变的)并且Python是垃圾收集的,所以只要消费者抓住它的引用,它可以继续访问它而不必担心其他线程正在做什么。可能发生的最糟糕的事情是你的程序使用来自几代self.thing
的大量内存保持活着。我有点好奇你的要求来自哪里。特别是,您并不关心thing
是否从未使用或多次使用过。