python os.fork是否使用相同的python解释器?

Ezr*_*zra 10 python multiprocessing

我知道Python中的线程使用相同的Python解释器实例.我的问题是与创建的流程相同os.fork吗?或者每个创建的进程os.fork都有自己的解释器吗?

Mar*_*cny 14

每当你分叉时,整个Python进程都会在内存中复制(包括 Python解释器,你的代码和任何库,当前堆栈等)以创建第二个进程 - 这就是为什么分支进程比创建一个线程要昂贵得多的原因之一.

这将创建python解释器的新副本.

运行两个python解释器的一个优点是你现在有两个GIL(全局解释器锁),因此可以在多核系统上进行真正的多处理.

一个进程中的线程共享相同的GIL,这意味着只有一个在给定时刻运行,只给出了并行性的错觉.


aba*_*ert 14

虽然fork确实创建了当前Python解释器的副本而不是运行相同的副本,但它通常不是您想要的,至少不是它自己的.其他问题包括:

  • 在某些平台上可能存在问题多线程进程的问题.一些库(最着名的Apple的Cocoa/CoreFoundation)可能会在后台为您启动线程,或者使用线程本地API,即使您只有一个线程等,在您不知情的情况下.
  • 一些库假设每个进程都将被正确初始化,但如果你fork在初始化之后不正确.最臭名昭着的是,如果你让sslPRNG在主进程中播种,那么你现在有了可能可预测的随机数,这是你安全的一个大漏洞.
  • 子文件继承了打开的文件描述符(作为重复项),平台之间的烦人方式的细节有所不同.
  • POSIX只需要平台在a fork和a之间实现一组非常具体的系统调用exec.如果您从未打过电话exec,则只能使用这些系统调用.这基本上意味着你无法轻易做任何事情.
  • 与信号有关的任何事情都特别令人讨厌并且在之后不可移植fork.

有关这些问题的详细信息,请参见POSIXfork或平台的联机帮助页.

正确的答案几乎总是使用multiprocessing,或concurrent.futures(包装multiprocessing)或类似的第三方库.

使用3.4+,您甚至可以指定启动方法.该fork方法基本上只是调用fork.该forkserver方法运行一个"干净"的过程(没有线程,信号处理程序,SSL初始化等)并从中分叉新的孩子.然后,该spawn方法调用或类似的方法来为您提供全新的解释器而不是副本.所以你可以先开始,然后如果有任何问题,切换到或者代码中的其他内容都不得更改.这很不错.forkexecposix_spawnforkforkserverspawn


Jam*_*lls 9

os.fork()相当于fork()许多UNIC中的系统调用.所以是的,您的子流程将与父级分开并具有不同的解释器(如此).

man fork:

FORK(2)

NAME fork - 创建子进程

大纲#include

   pid_t fork(void);
Run Code Online (Sandbox Code Playgroud)

说明fork()通过复制调用进程来创建新进程.新进程(称为子进程)与调用进程完全相同,称为父进程,但以下几点除外:

pydoc os.fork():

os.fork()叉子进程.在子级中返回0,在父级中返回子级的进程ID.如果发生错误,则引发OSError.

请注意,从线程使用fork()时,某些平台(包括FreeBSD <= 6.3,Cygwin和OS/2 EMX)都存在已知问题.

另请参阅:Martin Konecny对"分叉"的原因和优势的回应:)

为简洁起见; 其他并发方法不涉及单独的进程,因此单独的Python解释器包括: