我使用每个进程都有队列的列表。另一个线程用于一个接一个地填充这些队列,然后进程从中获取数据。问题是,过了一段时间,队列从进程内部引发了空异常,但线程却获得了完整异常。当我检查队列大小时,它与异常一致。 更糟糕的是,这种行为只能作为大型代码库的一部分进行复制,而我无法生成一个小型程序来对此进行复制。 是否有人在多进程队列在不同进程中不一致时遇到类似问题?
在管道的描述中添加更多内容。我有多个工作程序对象,每个工作程序都有一个输入队列(multiprocessing.Queue
),一个工作队列(multiprocessing.Queue
),一个输出队列(threading.Queue
)和一个工作进程({{1} })和管理器线程(multiprocessing.Process
)。
针对所有这些工作程序,我有一个馈线线程(threading.Thread
),该线程将样本标识符一一添加到所有工作程序的输入队列中。样本标识符的大小(文件路径)非常小,因此供稿器线程可以跟上进程。
工作人员从输入队列中获取样本标识符,读取这些样本,对其进行处理,然后将其逐个放入工作人员队列。管理器线程读取工作队列中的数据并将其放入输出队列中,因为threading.Thread
读取速度较慢。
所有multiprocessing.Queue
和.get()
调用都有超时,我跟踪从该管道中获取新数据所花费的时间。我还具有关闭和重新打开它的机制,方法是加入所有进程和线程(甚至用于队列),然后从头开始重新创建它们。当一切正常时,主进程遍历工作进程,并逐一读取其输出队列中的数据。大多数情况下,读取新数据还需要花费几毫秒的时间。
整个管道在我的代码中存在两次(用于使用Tensorflow进行机器学习)。一个实例用于培训,并在程序开始时创建,另一个实例用于测试。经过一段时间的训练后创建了第二个实例,它遍历了我的所有数据集,然后重置。当第二个实例第二次运行时,它在经过1000个左右的采样后被卡住。当它卡住并且在主进程中进入调试模式时,我看到输入队列已满,工作队列和输出队列为空。然后,当我进入一个工作进程的内部时,我看到它们的输入队列为空。似乎由于某种原因,工作进程看到的输入队列与应有的队列不同。请注意,这不是竞赛问题,因为此结果是稳定的。
我将程序挂起的位置归零。似乎对读取的文件数据执行.put()
。这意味着问题与最初描述的问题不同。进程挂起,看不到空队列。
打开文件的代码:
json.loads()
我尝试使用with open(json_path, 'r') as f:
data = f.read()
json_data = json.loads(data) # <== program hangs at this line
包来查明signal.alarm
中程序挂起的位置,但不会引发异常。也可以用单个json.loads()
重现该问题,但是在主过程中完成所有处理后,就不会出现此问题。
给任何人敲钟?