我试图加速Python程序,我注意到有一个线程总是在运行,它扫描来自外部资源的输入,当它获得某些东西时,它将调用另一个将解析输入数据的函数,返回一个可理解的信息(解析函数也使用其他函数)。
scanning()
函数的简单模型
def scanning(x):
alpha = GetSomething(x)
if alpha != 0:
print Parsing(alpha)
所以我的想法是将这个线程转换为一个与主进程并行运行的进程,当它获得某些东西时,它会使用Queue将它发送到主进程,然后主进程应该调用解析函数。
我的问题是:可以保持scanning()
函数不变并在进程中使用它(即使它调用其他函数)?
如果没有,scanning()
函数的结构需要对multiprocessing
模块方便地使用哪些修改?
对在Python中调用其他函数的函数进行多处理的正确方法是什么?
答案 0 :(得分:1)
简短回答:是的,有可能。
要了解原因,您需要了解有关多处理的一件事。它不会将multiprocessing
- 调用的函数移除到一个单独的进程中:它会创建整个进程的完整副本:包括它的代码,加载的模块以及已初始化的所有全局数据 之前,你分叉了你的流程。
因此,如果您的代码定义了一些子函数,则在将函数拆分为单独的进程以及已预先初始化的任何数据后,它们将可用于您的函数。对主进程之后分叉进程的值,函数和命名空间的任何修改都不会影响分叉进程 - 您需要使用特殊工具在进程之间进行通信。
所以,我们假设你有以下抽象代码:
import SomeModule
define SomeFunction()
assign SomeValue
define ChildProcess():
call SomeFunction()
increase SomeValue
do ChildProcessStuff
start ChildProcess()
decrease SomeValue
do MainProcessStuff
对于主进程和生成进程,您的代码执行相同,直到行start ChildProcess()
。在此行之后,您的流程会分为两个,这两个流程最初完全相同,但具有不同的执行点。主要流程超过此行并直接进入do MainProcessStuff
,而您的子流程永远不会到达该行。相反,它创建了整个命名空间的副本,并开始执行ChildProcess(),就好像它被调用为正常函数后跟exit()
一样。
请注意主进程和子进程如何访问SomeValue
。还要注意它们对它的更改是如何独立的,因为它们在不同的命名空间中进行(因此对不同的SomeValue
s)。 threading
模块不会分割命名空间,这是一个重要的区别。
另请注意,主进程从不执行ChildProcess
中的代码,但它保留对它的引用,可用于跟踪它的进度,过早终止等等。
您可能还对有关Python线程和进程here的更深入信息感兴趣。