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



我知道python中的线程使用python解释器的实例。我的问题与os.fork创建的过程相同吗?或os.fork创建的每个过程都有其自己的解释器?

每当您分叉时,整个python进程都会在内存中重复(包括 python Instraper,您的代码和任何库,当前堆栈等)以创建一个第二个过程 - 分叉一个过程比创建线程要贵得多的原因。

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

让两个Python解释器运行的一个优点是您现在有两个Gil(全局解释器锁),因此可以在多核系统上具有真实的多处理。

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

,而 fork确实确实创建了当前python解释器的副本,而不是使用相同的副本,通常不是您想要的,至少不是单独的。除其他问题:

  • 在某些平台上分配多线程流程可能会出现问题。一些图书馆(最著名的是苹果的可可/核心梦)可能在后台为您启动线程,或者即使您只有一个线程等,即使您只有一个线程等,也可以使用线程 - 本地API。
  • 一些库假定每个过程都会正确初始化,但是如果您在初始化后fork,则不为。最臭名昭著的是,如果让ssl在主要过程中播种其PRNG,那么叉子,您现在有可能可预测的随机数,这是您安全性的一个大漏洞。
  • 开放的文件描述符是孩子继承(作为DUP)的,在平台之间以令人讨厌的方式有所不同。
  • POSIX仅需要平台即可在forkexec之间实现非常特定的SYSCALL集。如果您从不致电exec,则只能使用这些SYSCALL。这基本上意味着您无法履行任何事情
  • 与信号有关的任何事情都是尤其是 fork之后令人讨厌且不容易出现。

有关这些问题的详细信息,请参见POSIX fork或您的平台的manpage。

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

使用3.4 ,您甚至可以指定一个开始方法。fork方法基本上只是调用forkforkserver方法运行一个"清洁"过程(没有线程,信号处理程序,SSL初始化等),并从中叉出新孩子。spawn方法调用fork,然后调用exec或等效的posix_spawn,以使您获得全新的解释器而不是副本。因此,您可以从fork,UT开始,然后如果有任何问题,请切换到forkserverspawn,并且代码中没有其他更改。这非常好。

os.fork()等于许多Unic(ES)中的fork() Syscall。因此,您的子过程(ES)将与父母分开,并具有不同的解释器(这样)。

man fork

叉(2)

名称 叉 - 创建子过程

摘要 #include

   pid_t fork(void);

描述 fork()通过复制调用过程来创建一个新的过程。新过程,称为孩子, 是调用过程的确切重复,除了以下几点外:

pydoc os.fork()

os.fork()叉一个子过程。在孩子和 父母的孩子的过程ID。如果发生错误,则Oserror是 提起。

请注意,某些平台在内 从线程使用fork()时有已知问题。

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

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

  • 绿色或轻质线;ala greenlet
  • Coroutines Ala Python发电机和新的Python 3 yield from
  • 异步I/O Ala Asyncio,扭曲,电路等

最新更新