2016-02-16 39 views
1

例如:下面的代碼運行正常在Ubuntu 14.04爲什麼子進程在Windows上啓動時導入主模塊,而不在Linux上?

# some imports 
import numpy as np 
import glob 
import sys 
import multiprocessing 
import os 

# creating some temporary data 
tmp_dir = os.path.join('tmp', 'nptest') 
if not os.path.exists(tmp_dir): 
    os.makedirs(tmp_dir) 
    for i in range(10): 
     x = np.random.rand(100, 50) 
     y = np.random.rand(200, 20) 
     file_path = os.path.join(tmp_dir, '%05d.npz' % i) 
     np.savez_compressed(file_path, x=x, y=y) 

def read_npz(path): 
    data = dict(np.load(path)) 
    return (data['x'], data['y']) 

def parallel_read(files): 
    pool = multiprocessing.Pool(processes=4) 
    data_list = pool.map(read_npz, files) 
    return data_list 

files = glob.glob(os.path.join(tmp_dir, '*.npz')) 
x = parallel_read(files) 
print('done') 

,但無法在Windows 7上,與沿行的錯誤消息:

cmd = get_command_line() + [rhandle] 
    pool = multiprocessing.Pool(processes=4) 
    File "C:\Anaconda\lib\multiprocessing\forking.py", line 358, in get_command_line 
    File "C:\Anaconda\lib\multiprocessing\__init__.py", line 232, in Pool 
    return Pool(processes, initializer, initargs, maxtasksperchild) 
    File "C:\Anaconda\lib\multiprocessing\pool.py", line 159, in __init__ 
    is not going to be frozen to produce a Windows executable.''') 
RuntimeError: 
      Attempt to start a new process before the current process 
      has finished its bootstrapping phase. 

      This probably means that you are on Windows and you have 
      forgotten to use the proper idiom in the main module: 

       if __name__ == '__main__': 
        freeze_support() 
        ... 

      The "freeze_support()" line can be omitted if the program 
      is not going to be frozen to produce a Windows executable. 
    self._repopulate_pool() 
    File "C:\Anaconda\lib\multiprocessing\pool.py", line 223, in _repopulate_pool 
    w.start() 
    File "C:\Anaconda\lib\multiprocessing\process.py", line 130, in start 
    self._popen = Popen(self) 
    File "C:\Anaconda\lib\multiprocessing\forking.py", line 258, in __init__ 
    cmd = get_command_line() + [rhandle] 
    File "C:\Anaconda\lib\multiprocessing\forking.py", line 358, in get_command_line 
    is not going to be frozen to produce a Windows executable.''') 
RuntimeError: 
      Attempt to start a new process before the current process 
      has finished its bootstrapping phase. 

      This probably means that you are on Windows and you have 
      forgotten to use the proper idiom in the main module: 

       if __name__ == '__main__': 
        freeze_support() 
        ... 

      The "freeze_support()" line can be omitted if the program 
      is not going to be frozen to produce a Windows executable. 

從我的理解,從事實上,這源於子進程在Windows上啓動時導入主模塊,而不在Linux上。通過將x = parallel_read(files)放置在主函數中可以防止Windows上的問題。例如:

if __name__ == '__main__':  
    x = parallel_read(files) 
    print('done') 

爲什麼子進程在Windows上啓動時導入主模塊而不在Linux上?

+0

由於Linux具有'fork'以啓動具有當前進程狀態的副本的新進程,而Windows沒有。 –

回答

2

Windows沒有fork函數。大多數其他操作系統都是這樣做的,在這些平臺上,multiprocessing使用它來啓動具有與父進程相同狀態的新進程。 Windows必須通過其他方式設置子進程的狀態,包括導入__main__模塊。

請注意,Python 3.4(及更高版本)允許您在所有操作系統上使用非分叉實現,如果您請求它。有關此功能的討論,請參閱bug追蹤器上的issue 8713

相關問題