<p>您可以为对<code>updateNumbers</code>的每次调用创建一个新线程,但是这种类型的更常见的方法是让1个线程在后台运行一个无限循环。您应该编写一个具有无限循环的方法或函数,该方法/函数将作为后台线程的目标。这种线程通常是一个守护进程,但它不是必须的。我修改了您的代码,以展示如何实现这一点(我还修复了示例代码中的一些小错误)。在</p>
<pre><code>from time import sleep, time
import threading
class Numbers(object):
def __init__(self, numbers):
self.data = numbers
self.lastUpdate = time()
class SimpleUpdater(object):
def __init__(self):
self.i = 5
self.updateDelta = 5
self.numbers = Numbers(list(range(self.i)))
self._startUpdateThread()
def _startUpdateThread(self):
# Only call this function once
update_thread = threading.Thread(target=self._updateLoop)
update_thread.daemon = True
update_thread.start()
def _updateLoop(self):
print("Staring Update Thread")
while True:
self.updateNumbers()
sleep(.001)
def updateNumbers(self):
numbers = self.numbers
delta = time() - numbers.lastUpdate
if delta < self.updateDelta:
return
print('Starting Update')
# artificial calculation time
sleep(4)
numbers = Numbers(list(range(self.i)))
self.numbers = numbers
print('Done Updating')
def runCounter(self):
# Take self.numbers once, then only use local `numbers`.
numbers = self.numbers
for j in numbers.data:
print(j)
sleep(0.5)
# do more with numbers
self.i += 1
if __name__ == '__main__':
S = SimpleUpdater()
while True:
S.runCounter()
</code></pre>
<p>请注意,我没有使用任何锁:)。{{{I>在不使用任何cdi}属性的情况下,都只能使用<cdi}属性来获得<cdi}的任何操作。对<code>self.numbers</code>的每个赋值都将一个新的<code>Numbers</code>对象与该属性相关联。每次访问该属性时,您应该期望得到一个不同的对象,但是如果您在方法的开头对该对象进行本地引用,即<code>numbers = self.numbers</code>,<code>numbers</code>将始终引用同一个对象(直到它在方法末尾超出作用域),即使后台线程更新了<code>self.numbers</code>。在</p>
<p>我创建一个<code>Numbers</code>类的原因是,我可以在单个(原子)赋值(数字列表和lastUpdated值)中获取和设置所有“volatile”成员。我知道这有很多需要跟踪的地方,老实说,使用锁可能更聪明、更安全:),但我也希望向您展示这个选项。在</p>