Windows, не хватает fork()
системный вызов, который дублирует текущий процесс. Это имеет много последствий, включая те, которые перечислены на странице документации windows multiprocessing. Более конкретно:
Bear in mind that if code run in a child process tries to access a global variable, then the value it sees (if any) may not be the same as the value in the parent process at the time that Process.start was called.
В внутренностях, питон создает новый процесс на окнах, начав новый процесс с нуля, и говорят это, чтобы загрузить все модули снова. Поэтому любое изменение, которое вы сделали в текущем процессе, не будет видно.
В вашем примере это означает, что в дочернем процессе ваш модуль будет загружен, но раздел if __name__ == '__main__'
не будет запущен. Поэтому T.init
не будет вызываться, а T.val
не будет существовать, таким образом, вы увидите ошибку.
С другой стороны, в системах POSIX (включая Linux) при создании процесса используется fork, и все глобальное состояние остается нетронутым. Ребенок работает с копией всего, поэтому ему не нужно ничего перезагружать и будет видеть свою копию T
с ее копией val
.
Это также означает, что процесс создания намного быстрее и намного легче при использовании ресурсов в системах POSIX, тем более что «дублирование» использует copy-on-write, чтобы избежать накладных расходов при фактическом копировании данных.
При использовании многопроцессорности существуют другие причуды, все из которых подробно описаны в python multiprocessing guidelines.
'fork' vs' spawn' - очень старая дискуссия. Ядро NT всегда имело возможность делать вилку с копированием на запись, но сам API Windows, выходящий из MS-DOS, не позволяет этого. Кроме того, существуют нетривиальные проблемы с форматированием многопоточного процесса, и в этом случае Python 3.4 предоставляет вам еще два варианта запуска в дополнение к «fork»: «forkserver» и «spawn». Последний является единственным вариантом в Windows. – eryksun
Это точно. Я всегда находил странный системный вызов fork, доступный в Win32, несмотря на то, что базовые функции присутствуют в ядре NT. Я не могу не видеть, что Microsoft не хочет сдаваться старым * «Те, кто не понимает Unix, обречены изобретать его». Черт, они дождались W2k8 до того, как окончательно добавили символические ссылки. Я готов поспорить, что в некоторых будущих версиях Windows будет '-эквивалент' fork() ', просто дайте им время. Возможно, с таким именем, как 'DuplicateCurrentProcess'. – spectras
Что я имею в виду, не позволяя этому способ, которым система эволюционировала из Windows 2.0, работающей на DOS, просто не будет работать с 'fork' - по крайней мере, не для активного процесса. Окно в режиме ядра (win32k.sys) расширяет структуры NT 'EPROCESS' и' ETHREAD' способами, для которых 'fork', вероятно, будет проблематичным, например, блокировкой. OTOH, для анализа процесса у нас есть возможность разблокировать инертный [моментальный снимок] (https://msdn.microsoft.com/en-us/library/dn457825). – eryksun