简体   繁体   English

python 多处理池的保存数据在 linux 上没有给出预期结果

[英]python save data of multiprocessing pool does not give expected result on linux

I'm trying to run many calculations at the same time using multiprocessing pool in python.我正在尝试使用 python 中的多处理池同时运行许多计算。 Each time a calculation is done I want to save the result in a file for later use.每次计算完成时,我都想将结果保存在文件中以备后用。 In the code below I'm trying to test this idea.在下面的代码中,我试图测试这个想法。 On windows I get the expected result of different output for each calculation.在 windows 上,每次计算我得到不同 output 的预期结果。 The same code on Linux has a problem because it outputs the same result for all calculations. Linux 上的相同代码存在问题,因为它为所有计算输出相同的结果。 I don't understand how to solve this problem on Linux.我不明白如何在 Linux 上解决这个问题。 Also, I would be happy to know how to save the data each time a calculations is done instead of waiting for all the calculations to be done and then saving all outputs at the same time.此外,我很高兴知道如何在每次计算完成时保存数据,而不是等待所有计算完成然后同时保存所有输出。 I've tried implementing different types of parallel computing with python using the examples on this site but couldn't get this issue fixed on Linux.我尝试使用此站点上的示例使用 python 实现不同类型的并行计算,但无法在 Linux 上解决此问题。 I've also searched for the past two days for solutions and couldn't find or understand how to fix this.过去两天我也在搜索解决方案,但找不到或不明白如何解决这个问题。 Any help would be really appreciated.任何帮助将非常感激。

This is my code:这是我的代码:

import multiprocessing
from functools import partial
import numpy as np
rng=np.random.default_rng()
import time

def sim(data_in_1, data_in_2, data_in_3, batch_num, run_number):

    file_str='run_'+str(run_number)+'.npy'
    temp=rng.choice(1000,5);
    time.sleep(temp[0]/1000)
    
    for i in range(temp[0]):
        a=np.sqrt(temp[1])
        
    return run_number, a, temp

def main():
    processes_num=8
    
    batch_num=1;
    num_of_calculations=8*2
    iterable=range(num_of_calculations);
    data_in_1=20;
    data_in_2=10;
    data_in_3=1;
    pool = multiprocessing.Pool(processes=processes_num)
    func = partial(sim, data_in_1, data_in_2, data_in_3, batch_num)
    results=pool.map(func, iterable)
    for r in results:
        out1=r
        file_str='run_'+str(out1[0])+'.npy'
        with open(file_str, 'wb') as f:
            np.save(f,out1[1])
            np.save(f,out1[2])
        print('saved run '+ str(out1[0]))
    pool.close()
    pool.join()
    
    print('Batch no. '+str(batch_num)+' is finished.')
    
    for run_number in range(num_of_calculations):
        file_str='run_'+str(run_number)+'.npy'
        with open(file_str, 'rb') as f:
            temp=np.load(f)
            temp=np.load(f)
        print('result of run ' + str(run_number) +' is: ' + str(temp))

if __name__ == "__main__":
    main()

Output on windows: windows 上的 Output:

saved run 0
saved run 1
saved run 2
saved run 3
saved run 4
saved run 5
saved run 6
saved run 7
saved run 8
saved run 9
saved run 10
saved run 11
saved run 12
saved run 13
saved run 14
saved run 15
Batch no. 1 is finished.
result of run 0 is: [173 600 438 195 877]
result of run 1 is: [925 710 727 604 759]
result of run 2 is: [883 645 558 875 205]
result of run 3 is: [843 541 597 605 513]
result of run 4 is: [342 439 406 101 192]
result of run 5 is: [472 279 796  99 774]
result of run 6 is: [443 982  49 314 854]
result of run 7 is: [383  45 923 356 156]
result of run 8 is: [344 597 675 615 297]
result of run 9 is: [605 241 523 241 570]
result of run 10 is: [330 457 172 670 130]
result of run 11 is: [ 38 926 902 659 782]
result of run 12 is: [573 150 435 216 765]
result of run 13 is: [178 851 878 155 431]
result of run 14 is: [929 749 730 368 504]
result of run 15 is: [235 310 836 940 701]

Output of same code on Linux: Linux 上相同代码的 Output:

saved run 0
saved run 1
saved run 2
saved run 3
saved run 4
saved run 5
saved run 6
saved run 7
saved run 8
saved run 9
saved run 10
saved run 11
saved run 12
saved run 13
saved run 14
saved run 15
Batch no. 1 is finished.
result of run 0 is: [  9 218 388 265 856]
result of run 1 is: [  9 218 388 265 856]
result of run 2 is: [  9 218 388 265 856]
result of run 3 is: [  9 218 388 265 856]
result of run 4 is: [  9 218 388 265 856]
result of run 5 is: [  9 218 388 265 856]
result of run 6 is: [  9 218 388 265 856]
result of run 7 is: [  9 218 388 265 856]
result of run 8 is: [715 532 364 775 437]
result of run 9 is: [715 532 364 775 437]
result of run 10 is: [715 532 364 775 437]
result of run 11 is: [715 532 364 775 437]
result of run 12 is: [715 532 364 775 437]
result of run 13 is: [715 532 364 775 437]
result of run 14 is: [715 532 364 775 437]
result of run 15 is: [715 532 364 775 437]

So it turns out that the random number generator seed gets inherited from the parent in Linux, but on windows it is changed for every process.所以事实证明,随机数生成器种子是从 Linux 中的父级继承的,但在 windows 上,它会针对每个进程进行更改。 That's why I kept getting the same result on Linux.这就是为什么我在 Linux 上一直得到相同结果的原因。 So I moved the line:所以我移动了这条线:

rng=np.random.default_rng()

from global to inside the function "sim" and that did the trick.从全局到 function “sim”内部,这就成功了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM