Python 为什么并行处理后无法到达我的打印语句?
我写了一个函数,它运行一系列化学反应的随机模拟,下面是该函数的简要总结:Python 为什么并行处理后无法到达我的打印语句?,python,class,time,multiprocessing,scoping,Python,Class,Time,Multiprocessing,Scoping,我写了一个函数,它运行一系列化学反应的随机模拟,下面是该函数的简要总结: def stochastic_simulation(*args): # arguments are a series of arrays t = SimulationTimer() t.start() update molecule numbers for each species in model update current time of the system t.stop(
def stochastic_simulation(*args): # arguments are a series of arrays
t = SimulationTimer()
t.start()
update molecule numbers for each species in model
update current time of the system
t.stop()
print(f"Accumulated time: {t.get_accumulated_time():0.10f} seconds")
return popul_num_all, tao_all, t.get_accumulated_time() # popul_num_all is an array of changing molecule numbers over time, tao_all is the evolution of time throughout the simulation.
SimulationTimer
是一个定制的计时器:
class TimeError(Exception):
"""A custom exception used to report errors in use of Timer Class"""
pass
class SimulationTimer:
def __init__(self):
self._simulation_start_time = None
self._simulation_stop_time = None
self.accumulated_elapsed_time = 0.0
def start(self):
"""start a new timer"""
if self._simulation_start_time is not None: # attribute
raise TimeError(f"Timer is running.\n Use .stop() to stop it")
self._simulation_start_time = time.perf_counter()
def stop(self):
"""stop the time and report the elsaped time"""
if self._simulation_start_time is None:
raise TimeError(f"Timer is not running.\n Use .start() to start it.")
self._simulation_stop_time = time.perf_counter()
elapsed_simulation_time = self._simulation_stop_time -
self._simulation_start_time
self.accumulated_elapsed_time += elapsed_simulation_time
self._simulation_start_time = None
print(f"Elapsed time: {elapsed_simulation_time:0.10f} seconds")
def get_accumulated_time(self):
""" Return the elapsed time for later use"""
return self.accumulated_elapsed_time
我正在尝试使用多处理
库的池
方法并行运行随机模拟
t.get_累计时间()
是指并行运行所有模拟所需的时间
if __name__ == '__main__':
with Pool() as p:
pool_results = p.map(stochastic_simulation, [start_state, LHS, stoch_rate, state_change_array])
total_time = 0.0
for tuple_results in pool_results:
total_time += tuple_results[2]
print(f"Total time:\n{total_time}")
上面的代码是我如何运行并行模拟的,其中有两个问题。首先,它从未实际到达print语句,f“Total time:\n{Total_time}”
从未被打印。其次,它从不返回运行所有并行模拟所用时间的一个组合度量值t。相反,它为每个进程返回一个单独的时间
我不确定这些问题是否与作用域类对象或多处理有关
编辑:
我对随机模拟的输入都是数组。
这说明了以下系统:
1S + 0T + 0U --> 0S + 0T + 0U
2S + 0T + 0U --> 0S + 1T + 0U
0S + 1T + 0U --> 2S + 0T + 0U
0S + 1T + 0U --> 0S + 0T + 1U
initial_state
这是每个分子物种在时间零点的数量。在我的模型中有4个物种,所以它的len=3
LHS
是不同反应的反应物之间比率的2D数组
stoch_rate
是长度为4的数组中每个反应的速率
state\u change\u array
是反应发生后分子的净变化
有什么建议吗?我使用下面的代码得到了一个最小的可复制示例:
import multiprocessing as mp
import time
def stochastic_simulation(*args): # arguments are a series of arrays
print('args are:', *args)
t = SimulationTimer()
t.start()
# update molecule numbers for each species in model
# update current time of the system
t.stop()
print(f"Accumulated time: {t.get_accumulated_time():0.10f} seconds")
return t.get_accumulated_time() # deleted some returns
class TimeError(Exception):
"""A custom exception used to report errors in use of Timer Class"""
pass
class SimulationTimer:
accumulated_elapsed_time = 0.0
def __init__(self):
self._simulation_start_time = None
self._simulation_stop_time = None
def start(self):
"""start a new timer"""
if self._simulation_start_time is not None: # attribute
raise TimeError(f"Timer is running.\n Use .stop() to stop it")
self._simulation_start_time = time.perf_counter()
def stop(self):
"""stop the time and report the elsaped time"""
if self._simulation_start_time is None:
raise TimeError(f"Timer is not running.\n Use .start() to start it.")
self._simulation_stop_time = time.perf_counter()
elapsed_simulation_time = self._simulation_stop_time - self._simulation_start_time
self.accumulated_elapsed_time += elapsed_simulation_time
self._simulation_start_time = None
print(f"Elapsed time: {elapsed_simulation_time:0.10f} seconds")
def get_accumulated_time(self):
""" Return the elapsed time for later use"""
return self.accumulated_elapsed_time
if __name__ == '__main__':
with mp.Pool() as p:
pool_results = p.map(stochastic_simulation, [1,2,3,4]) #changed inputs
print(pool_results)
total_time = 0.0
for tuple_results in pool_results:
total_time += tuple_results #removed the [2] index
print(f"Total time:\n{total_time}")
输出:
args are: 1
Elapsed time: 0.0000015800 seconds
Accumulated time: 0.0000015800 seconds
args are: 2
Elapsed time: 0.0000011850 seconds
Accumulated time: 0.0000011850 seconds
args are: 3
Elapsed time: 0.0000007900 seconds
Accumulated time: 0.0000007900 seconds
args are: 4
Elapsed time: 0.0000007900 seconds
Accumulated time: 0.0000007900 seconds
[1.580000000001025e-06, 1.184999999986891e-06, 7.900000000005125e-07, 7.900000000005125e-07]
Total time:
4.344999999988941e-06
这让我相信你的输入可能有点古怪……不确定你在计时器之间要做什么计算,但会试图缩小代码停止的确切范围
此外,如果您想运行4个模拟,每个模拟有4个参数,您应该提供参数列表,即[[1,2,3,4],[4,3,2,1],[23,23,63,2],[6,2,1,5]。
请编辑代码以修复缩进。我们无法判断哪些项应该是SimulationTimer
类的成员,也无法判断如果name
块中的下应该缩进哪些代码。可能的重复:根据我的经验,您不能在控制台中从具有父进程的子进程打印()到stdout。您可以将流程标识符添加到要打印的字符串中,将该字符串保存在变量中,并将其返回到父流程,然后在那里打印。此外,您的类变量“累计\已用\时间”应该是一个实例变量,而不是在init下定义的。例如,in parallel是指4个并行模拟,每个模拟有1个参数吗?或者,您是指1个(或更多)并行模拟的示例,每个模拟有4个参数想知道p.map中是否有意外行为,只是想更好地理解缩进。我试图用所有必需的参数(4个参数)运行整个“随机模拟”函数4次。请分享您输入的实际情况,以便更好地了解您试图用它们做什么,我有一种感觉,这实际上可能是一个星图问题,但它只是没有以那种方式表达出来。请看编辑,输入是什么,这是你的意思吗?另一件事是我需要你删除的返回,因为它们被传递到另一个函数,并用于绘制一个分子数随时间变化的图表我没有你的输入,你也没有任何代码在你的OP中生成这些返回,所以我将它们注释掉,并能够在稍作修改的情况下运行它,这让我相信问题出在生成这两个返回的函数上,或者说是输入本身。抱歉,刚才的评论太晚了!我对打印子进程等做了更多的研究,只是想问一下您使用了什么操作系统来让上述代码正常工作?你用过叉子吗?我现在在Windows上,不知道这是否是我的问题的一部分。我用windows10来做这个,不知道分叉意味着什么,但我要说不