为什么python多进程中,子进程会重复执行主进程代码,fork机制到底是怎么执行的

代码例子如下,求大神解疑:我的疑惑是在子进程为什么会在全局代码块上执行了一次 write 的操作,但是没进行print操作

#一个有趣的例子:
#正确的输出是: 主 子  主
#你想想为什么呢?
# 为什么打印输出  --代码块--,--子--- ,而文件输出是 主  子 主 ???
import os
from multiprocessing import Process,get_start_method,set_start_method
file=open('./name.txt','w+',encoding='utf-8')
pid =str(os.getpid())
file.write("主:"+pid+"\n")
print("----代码块-----")
def write_info():
    pid = str(os.getpid())
    file.write("子:"+pid+'\n')
    print("------子线程------")
    file.flush()
if __name__ == '__main__':
    set_start_method('fork')
    p1=Process(target=write_info)
    p1.start()
    # print(get_start_method())
    p1.join()
    file.close()

终端输出结果:
为什么python多进程中,子进程会重复执行主进程代码,fork机制到底是怎么执行的
文件内容:

为什么python多进程中,子进程会重复执行主进程代码,fork机制到底是怎么执行的

Jason990420
最佳答案

fork

The parent process uses os.fork() to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process. Note that safely forking a multithreaded process is problematic. [Available on Unix only. The default on Unix.]

我的系统是WIN10, 只有 'spawn' 方法, 所以只能猜一下

  • 在主进程的文件缓冲写入 '主'
  • 在子进程的文件缓冲同主进程的文件缓冲一樣, 写入 '子' (此时子进程中的缓冲, 已有 '主', '子')
  • 在子进程, 调用 file.flush(), 文件中写入 ('主', '子')
  • 回到主进程, 调用 file.close(), 文件中再写入主进程的文件缓冲中的 '主', 文件关闭.

所以文件中的内容为

  • 子进程的文件缓冲 + 主进程的文件缓冲
  • ('主', '子') + ('主',), 也就是 ('主', '子', '主')
1个月前 评论
讨论数量: 3
Jason990420

fork

The parent process uses os.fork() to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process. Note that safely forking a multithreaded process is problematic. [Available on Unix only. The default on Unix.]

我的系统是WIN10, 只有 'spawn' 方法, 所以只能猜一下

  • 在主进程的文件缓冲写入 '主'
  • 在子进程的文件缓冲同主进程的文件缓冲一樣, 写入 '子' (此时子进程中的缓冲, 已有 '主', '子')
  • 在子进程, 调用 file.flush(), 文件中写入 ('主', '子')
  • 回到主进程, 调用 file.close(), 文件中再写入主进程的文件缓冲中的 '主', 文件关闭.

所以文件中的内容为

  • 子进程的文件缓冲 + 主进程的文件缓冲
  • ('主', '子') + ('主',), 也就是 ('主', '子', '主')
1个月前 评论

通过你的解答加上我查阅的spwan 和 fork 机制,我大概知道原因。fork 创建的子进程会继承主进程的资源,从创建处执行函数。所以全局代码块中的 write 主被带入子进程中,并且在子进程flush 后被写入,子进程结束。主进程关闭文件,把主进程命名空间内存中写的主也刷新到文件里。 而spwan 模式子进程相当于拷贝一份新的进程,他的资源都是新生成的并不继承与主进程,新生成他就要导入包,程序自上向下执行。大概这么一回事。

1个月前 评论

这个问题主要Python multiprocessing 不同操作系统体现的不同创建进程的方式 fork 和 spwan 的区别,欢迎大家补充讨论!

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!