来自https://stackoverflow.com/a/53504673/9191338后:

派生对象被克隆,并在每个进程中最终确定每个对象

fork/forkserver对象在主流程中共享和最终确定

事实似乎是这样:

import os
from multiprocessing import Process
import multiprocessing
multiprocessing.set_start_method('fork', force=True)

class Track:
    def __init__(self):
        print(f'{os.getpid()=} object created in {__name__=}')
    
    def __getstate__(self):
        print(f'{os.getpid()=} object pickled in {__name__=}')
        return {}
    
    def __setstate__(self, state):
        print(f'{os.getpid()=} object unpickled in {__name__=}')
        return self

    def __del__(self):
        print(f'{os.getpid()=} object deleted in {__name__=}')

def f(x):
    print(f'{os.getpid()=} function executed in {__name__=}')

if __name__ == '__main__':

    x = Track()

    for i in range(2):
        print(f'{os.getpid()=} Iteration: {i}, Process object created')
        p = Process(target=f, args=(x,))
        print(f'{os.getpid()=} Iteration: {i}, Process created and started')
        p.start()
        print(f'{os.getpid()=} Iteration: {i}, Process starts to run functions')
        p.join()

输出是:

os.getpid()=30620 object created in __name__='__main__'
os.getpid()=30620 Iteration: 0, Process object created
os.getpid()=30620 Iteration: 0, Process created and started
os.getpid()=30620 Iteration: 0, Process starts to run functions
os.getpid()=30623 function executed in __name__='__main__'
os.getpid()=30620 Iteration: 1, Process object created
os.getpid()=30620 Iteration: 1, Process created and started
os.getpid()=30620 Iteration: 1, Process starts to run functions
os.getpid()=30624 function executed in __name__='__main__'
os.getpid()=30620 object deleted in __name__='__main__'

事实上,该对象仅在主过程中被删除.

我的问题是,这是如何实现的?虽然新流程是从主流程派生出来的,但Forking 之后,新流程本质上是另一个流程,这两个流程如何共享gc信息呢?

此外,gc信息共享是针对每个对象进行,还是仅针对作为子流程参数传递的对象进行?

推荐答案

在Linux上创建子进程时使用fork start_方法,一旦函数结束,Python就会使用os._exit()(请注意虚线)来终止子进程.这在某种程度上相当于进程崩溃,因此没有任何 destruct 函数被调用的机会,进程只是终止,操作系统只是收回分配给该进程的任何资源.

因此,您不应该依赖子进程调用的析构函数来释放资源.(例如关闭外部服务器)

Python相关问答推荐

如何修复fpdf中的线路出血

是否有方法将现有的X-Y图转换为X-Y-Y1图(以重新填充)?

Flask主机持续 bootstrap 本地IP| Python

使用Beautiful Soup获取第二个srcset属性

使用argsorted索引子集索引数组

如何销毁框架并使其在tkinter中看起来像以前的样子?

在Pandas框架中截短至固定数量的列

如何在Python中使用io.BytesIO写入现有缓冲区?

max_of_three使用First_select、second_select、

查找两极rame中组之间的所有差异

从groupby执行计算后创建新的子框架

Python解析整数格式说明符的规则?

SQLAlchemy Like ALL ORM analog

将输入聚合到统一词典中

有没有一种ONE—LINER的方法给一个框架的每一行一个由整数和字符串组成的唯一id?

Python导入某些库时非法指令(核心转储)(beautifulsoup4."" yfinance)

什么是合并两个embrame的最佳方法,其中一个有日期范围,另一个有日期没有任何共享列?

Django admin Csrf令牌未设置

使用Python查找、替换和调整PDF中的图像'

基于另一列的GROUP-BY聚合将列添加到Polars LazyFrame