python中并行任务的良好实践

时间:2019-01-02 08:56:18

标签: python multithreading multiprocessing

我有一个python脚本正在生成数据,一个正在用张量流和keras对该数据进行训练的神经网络。两者都需要神经网络的实例。

由于我尚未将标志设置为“ allow growth”(允许增长),因此每个进程都会占用全部GPU内存。因此,我只给每个进程提供自己的GPU。 (对于只有一个GPU的人来说可能不是一个好的解决方案,而另一个未解决的问题)

实际问题如下:两个实例都需要访问网络权重文件。我最近遇到了很多崩溃,因为两个进程都试图访问权重。一个标志或类似的东西应该阻止每个进程访问它,而另一个进程正在访问。希望这不会造成瓶颈。 我试图提出一种解决方案,例如C中的信号量,但是今天我在堆栈交换中找到了这个post

重命名的想法对我来说似乎很简单且有效。就我而言,这是好习惯吗?我将使用自己的功能创建重量文件

self.model.save_weights(filepath='weights.h5$$$')

在学习过程中,使用

保存后将其重命名
os.rename('weights.h5$$$', 'weights.h5')

并使用功能

将它们加载到我的数据生成过程中
self.model.load_weights(filepath='weights.h5')

此重命名会覆盖旧文件吗?如果当前正在加载其他进程,会发生什么?我希望其他想法能使我的脚本实现多线程/多进程。刚刚意识到,在顺序脚本中生成数据,学习,生成数据……并不能真正发挥作用。

编辑1:忘记提及权重是由keras的保存功能存储在.h5文件中的

1 个答案:

答案 0 :(得分:3)

multiprocessing模块具有一个RLock类,您可以用来控制对分片资源的访问。 如果您记得在读写之前先获取锁,然后再释放它,则此方法也适用于文件。使用锁意味着某些时候某个进程无法读取或写入文件。这有多少问题取决于两个进程必须访问文件的数量。

请注意,要使其正常工作,其中一个脚本必须在创建锁后以Process 的形式启动另一个脚本。

如果权重是Python数据结构,则可以将其置于multiprocessing.Manager的控制之下。那将为您管理对其控制下的对象的访问。 请注意,Manager不能用于文件,而只能用于内存中的对象

此外,在类似UNIX的操作系统上,Python具有os.lockf来锁定文件(部分)。请注意,这只是一个 advisory 锁。也就是说,如果另一个进程调用lockf,则返回值表明该文件已被锁定。它实际上并不会阻止您读取文件。

注意: 可以读取和写入文件。 当两个进程正在读取(读取/读取)同一文件时,此功能可以很好地工作。其他所有组合(读/写,写/读,写/写)都可能并最终导致不确定的行为和数据损坏。

注意2: 另一种可能的解决方案涉及进程间通信。 进程1写入一个新的h5文件(带有随机文件名),将其关闭,然后向进程2发送一条消息(使用PipeQueue到进程2“我已经写了一个新的参数文件\ path \ to \ file”。 然后,进程2读取文件并将其删除。这可以双向工作,但需要两个进程都经常检查和处理消息。这样可以防止文件损坏,因为写入过程只会在完成文件后 通知读取过程。