我正在使用多处理模块来分叉子进程。由于在分叉时,子进程获取父进程的地址空间,因此我为父进程和子进程获取相同的记录器。我想清除从父进程继承的任何值的子进程的地址空间。我知道多处理在较低级别执行 fork() 但不是 exec()。我想知道在我的情况下使用多处理是否好,或者我应该使用 os.fork() 和 os.exec() 组合还是有其他解决方案?
谢谢。
我正在使用多处理模块来分叉子进程。由于在分叉时,子进程获取父进程的地址空间,因此我为父进程和子进程获取相同的记录器。我想清除从父进程继承的任何值的子进程的地址空间。我知道多处理在较低级别执行 fork() 但不是 exec()。我想知道在我的情况下使用多处理是否好,或者我应该使用 os.fork() 和 os.exec() 组合还是有其他解决方案?
谢谢。
由于multiprocessing
正在从您的程序中运行一个函数,就好像它是一个线程函数一样,它肯定需要您的进程状态的完整副本。这意味着做fork()
.
使用由 提供的更高级别的接口multiprocessing
通常更好。至少你自己不应该关心fork()
返回码。
os.fork()
是一个较低级别的功能,提供较少的开箱即用服务,尽管您当然可以将它用于任何用途......以部分重新实现代码multiprocessing
为代价。multiprocessing
所以,我认为,multiprocessing
对你来说应该没问题。
但是,如果您处理的内存占用太大而无法复制它(或者如果您有其他原因避免分叉——打开与数据库的连接、打开日志文件等),您可能必须创建要运行的函数一个新的进程一个单独的 python 程序。然后您可以使用 运行它subprocess
,将参数传递给它stdin
,捕获它stdout
并解析输出以获得结果。
UPD: os.exec...
函数系列很难用于大多数用途,因为它用衍生的进程替换了您的进程(如果您运行与正在运行的程序相同的程序,它将从一开始就重新启动,而不保留任何内存数据)。但是,如果确实不需要继续父进程执行,exec()
可能会有一些用处。
根据我的个人经验:os.fork()
经常用于在 Unix 上创建守护进程;我经常使用subprocess
(通信是通过stdin/stdout);几乎从不使用多处理;我一生中没有一次需要os.exec...()
。
您可以将子进程中的记录器重新绑定到它自己的。我不知道其他操作系统,但在 Linux 上,分叉不会复制整个内存占用(正如 Ellioh 所提到的),而是使用“写时复制”概念。因此,直到您更改子进程中的某些内容 - 它仍保留在父进程的内存范围内。例如,您可以 fork 100 个子进程(不写入内存,只读取)并检查整体内存使用情况。不会parent_memory_usage * 100
,但更少。