2016-02-16 6 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. Проблема с Windows может быть предотвращена путем помещения x = parallel_read(files) в основную функцию. Например:

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

Почему подпроцессы импортируют основной модуль при запуске в Windows, пока они не работают в Linux?

+0

Поскольку у Linux есть 'fork', чтобы запускать новые процессы с копией состояния текущего процесса, а Windows - нет. –

ответ

2

Windows не имеет функции fork. Большинство других ОС, и на этих платформах используется multiprocessing для запуска новых процессов с тем же состоянием, что и родительский процесс. Windows должна настроить состояние дочернего процесса другими способами, включая импорт модуля __main__.

Обратите внимание, что Python 3.4 (и более поздние версии) позволяет вам использовать реализацию без forking во всех операционных системах, если вы ее запросите. См. issue 8713 в разделе отслеживания ошибок для обсуждения этой функции.

 Смежные вопросы

  • Нет связанных вопросов^_^