如果您不是“受过培训的程序员”,这应该会有所帮助:
我想我已经理解了上面和网上其他地方的技术解释,但我总是有一个问题“很好,但我为什么需要它?什么是实用的用例?”。而现在生活给了我一个很好的例子,澄清了一切:
我正在使用它来控制由多线程模块实例化的类的实例之间共享的全局共享变量。用人性化的语言,我正在运行多个代理,它们为并行的深度学习创建示例。 (想象多个玩家同时玩 ATARI 游戏,每个人都将游戏结果保存到一个公共存储库(共享变量))
我使用以下代码(在主/执行代码中)实例化播放器/代理:
a3c_workers = [A3C_Worker(self.master_model, self.optimizer, i, self.env_name, self.model_dir) for i in range(multiprocessing.cpu_count())]
- 它创建的玩家数量与我的电脑上的处理器内核数量一样多
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):,将需要我们为每个实例单独重置该计数器,这将需要更多计算且难以跟踪。