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

时间:2015-05-11 00:01:32

标签: python multiprocessing

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

3 个答案:

答案 0 :(得分:14)

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

  • 在某些平台上可能存在问题多线程进程的问题。有些库(最着名的是Apple的Cocoa / CoreFoundation)可能会在后台为你启动线程,或者使用线程本地API,即使你只是在你不知情的情况下只有一个线程等。
  • 有些库假定每个进程都会正确初始化,但如果你在初始化后fork不正确。最臭名昭着的是,如果你让ssl在主进程中播种它的PRNG,那么你现在有可能可预测的随机数,这是你安全的一个大漏洞。
  • 开放文件描述符由子项继承(作为重复),其中的详细信息在平台之间以恼人的方式变化。
  • POSIX仅需要平台在forkexec之间实现一组非常具体的系统调用。如果您从未致电exec,则只能使用这些系统调用。这基本上意味着你无法移植任何东西
  • fork之后,任何与信号有关的内容都是,尤其是令人烦恼且无法移植。

有关这些问题的详细信息,请参阅POSIX fork或您平台的联机帮助页。

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

使用3.4+,您甚至可以指定start methodfork方法基本上只调用forkforkserver方法运行单个“干净”进程(没有线程,信号处理程序,SSL初始化等)并从中分离新的子进程。 spawn方法会调用fork,然后调用exec,或类似posix_spawn,以便为您提供全新的解释器,而不是副本。因此,您可以从fork开始,如果有任何问题,请切换到forkserverspawn,您的代码中的任何其他内容都不得更改。这很不错。

答案 1 :(得分:13)

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

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

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

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

答案 2 :(得分:9)

os.fork()相当于许多UNIC中的fork()系统调用。所以您的子流程将与父流分开并拥有不同的解释器(本身)。

man fork

  

FORK(2)

     

NAME          fork - 创建子进程

     

概要          #include

   pid_t fork(void);
     

说明          fork()通过复制调用进程来创建一个新进程。新过程,称为儿童,          是调用进程的完全重复,称为父进程,但以下几点除外:

pydoc os.fork()

  

os.fork()分叉子进程。在孩子和...返回0   父级中的子进程ID。如果发生错误OSError是   提高。

     

请注意,某些平台包括FreeBSD< = 6.3,Cygwin和OS / 2 EMX   从线程中使用fork()时会出现已知问题。

另见:Martin Konecny对于"分叉的原因和优势的回应" :)

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