如果您不是“受过培训的程序员”,这应该会有所帮助:
我想我已经理解了上面和网上其他地方的技术解释,但我总是被一个问题留下“很好,但我为什么需要它?什么是实用的用例?”。现在生活给了我一个很好的例子,澄清了一切:
我正在使用它来控制在由多线程模块实例化的类的实例之间共享的全局共享变量。在人性化的语言中,我正在运行多个代理,它们为并行的深度学习创建示例。(想象多个玩家同时玩 ATARI 游戏,每个玩家都将游戏结果保存到一个公共存储库(共享变量))
我使用以下代码(在主/执行代码中)实例化玩家/代理:
a3c_workers = [A3C_Worker(self.master_model, self.optimizer, i, self.env_name, self.model_dir) for i in range(multiprocessing.cpu_count())]
- 它创建与我的 comp A3C_Worker 上的处理器内核一样多的玩家 - 是一个定义代理 a3c_workers 的类 - 是该类的实例列表(即每个实例都是一个玩家/代理)
现在我想知道所有玩家/代理已经玩了多少游戏,因此在 A3C_Worker 定义中我定义了要在所有实例之间共享的变量:
class A3C_Worker(threading.Thread):
global_shared_total_episodes_across_all_workers = 0
现在,当工人完成他们的游戏时,他们每完成一场游戏,就会将计数增加 1
在我的示例生成结束时,我正在关闭实例,但共享变量分配了所玩游戏的总数。所以当我再次重新运行它时,我最初的总集数是之前的总集数。但我需要该计数来代表每次运行的值
解决我指定的问题:
class A3C_Worker(threading.Thread):
@classmethod
def reset(cls):
A3C_Worker.global_shared_total_episodes_across_all_workers = 0
比我刚刚调用的执行代码:
A3C_Worker.reset()
请注意,这是对整个 CLASS 的调用,而不是单独调用它的任何实例。因此,从现在开始,对于我启动的每个新代理,它都会将我的计数器设置为 0。
使用通常的方法定义def play(self):
,将需要我们为每个实例单独重置该计数器,这对计算的要求更高且难以跟踪。