bounty将于明天到期。回答此问题可获得+50的声望奖励。James Huang希望吸引更多人关注此问题。
我这里有一些多处理代码,试图同时运行多个astroscrappy进程。然而,当它实际上必须调用astroscrappy时,一切都停止了。我在jupyter笔记本上运行这个。
def a_test(i, q):
import astroscrappy
print(1)
path = i
s = fits.getdata(path)
print(2)
print(2.5)
a = astroscrappy.detect_cosmics(s)
print(3)
q.put([a, i])
bundle = []
import multiprocessing as mp
queue = mp.Manager().Queue()
processes = []
for k, item in enumerate(paths):
processes.append(mp.Process(target=a_test, args=(item, queue)))
# Run processes
for p in processes:
p.start()
for p in processes:
bundle.append(queue.get())
它只能打印出1,2,2.5,但是不能打印出调用astroscrapy后的3。你知道为什么它不能工作吗?
2条答案
按热度按时间h7appiyu1#
这段代码产生了多个进程,每个进程都必须有适当的终止时间。为每个进程调用
join()
就是这样做的。我测试了下面的3个文件的代码,并且能够观察到进程的并发性。在我的机器上执行时间是7-9秒。输出:
这段代码不能在jupyter notebook中运行,要了解为什么
multiprocessing
不能在jupyter notebook中正常工作,你可以参考this discussion。但是有一个变通方法,要让这段代码在Jupyter notebook中工作,需要从一个单独的python文件调用
a_test
,例如,我创建了一个名为 * functest.py * 的python文件(在您的notebook运行的同一目录中),代码如下:现在,在你的笔记本电脑中运行下面的代码。注意,我使用了
Pool
而不是Process
,并且输出将不会有来自a_test
的print语句,如1,2,2,5等。我特意将它们从a_test
中删除,因为它们不会打印到Jupyter笔记本电脑输出。相反,我打印出bundle
来验证处理。输出:
multiprocessing
的另一个替代品是concurrent.futures
模块,它在jupyter notebook上运行没有任何问题,下面的代码可以在jupyter notebook上运行,我可以把执行时间降低到5-6秒。输出:
另一个选择是使用
threading
模块。这里有一个可以在jupyter中运行的简单示例。我得到的执行时间大约为5-6秒。输出:
请注意,如果您不需要在该函数之外处理
a_test
的结果,那么您就不需要从该函数返回任何内容,这将进一步保存时间。我也用
joblib
运行了一些测试,重构了您的代码,并在下面分享了一些测试结果:输出:
print语句的输出没有出现在jupyter notebook的输出中,但是执行时间在6-7秒的范围内。
总之,我没有观察到任何方法在执行时间上有显著的时间差异。这也可能是因为我尝试了一个小数据集(只有3个文件)。然而,
concurrent.futures
始终显示出稍好的结果。您可以尝试所有这些方法,并比较哪一种方法最适合您的用例。bxpogfeg2#
使用joblib的Parallel,我能够使这段代码运行得更快,而不会卡住。
我运行了几次,与不使用并行的代码相比,它的运行速度几乎快了两倍,仍然不知道为什么多处理不起作用,但至少它起作用了。
编辑:在较大的数据集上运行并做了一些额外的调整后,这里的代码实际上并没有运行速度的两倍快,实际上比同步代码要慢一些。