我正在努力使用下面的代码使用Multiprocessing的Process函数同时运行2个函数。我最终的努力是运行一个计时器,该计时器将在脚本的主体内进行检查。如果时间已经完成,那么主体中的依赖将触发自己的动作。如果时间尚未完成,它将转到下一个动作。
我在带有构建的MacBook Pro上运行它: 处理器名称:Intel Core 2 Duo 处理器速度:2.66 GHz 处理器数量:1 核心总数:2
脚本:
#!/usr/bin/pyton
# MODULES
import time
from multiprocessing import Process
# GLOBAL VARIABLES
Completion = ''
# FUNCTIONS
def Timer(duration):
global Completion
Ticker = 0
while Ticker != duration:
Ticker = Ticker + 1
print(Ticker)
time.sleep(1)
Completion = '{0}TickerDone'.format(duration)
def Wait(seconds):
time.sleep(seconds)
#MAIN
P1 = Process(target = Timer(10))
P1.start()
P2 = Process(target = Wait(11))
P2.start()
P1.join()
P2.join()
print(Completion)
if Completion == '10TickerDone':
print('Good to go!\n')
else:
print('Not yet!\n')
# END
这两个函数执行的操作除外,但是第二个函数(仅用于完成第一个函数等待10 + 1秒)仅在第一个函数10秒计时器完成后才开始。因此,在本质上,我必须等待21秒才能测试10秒计时器。
结果:
$ python Test.py
1
2
3
4
5
6
7
8
9
10
10TickerDone
Good to go!
我需要做的是并行运行这两个函数,这样第二个函数可以在执行第三个函数之前测试第一个函数是否完成。
我哪里错了?
答案 0 :(得分:1)
你的主要问题是你没有在子进程中运行目标函数,而是在启动另一个进程之前直接运行。
当您执行以下代码时:
P1 = Process(target = Timer(10))
Python将imediattely解析target=
部分左侧的表达式 - 并调用该函数,将等待10秒,然后,创建一个子进程对象,其目标实际上是返回值该功能(None
)。
所以,如果你这样做:
#MAIN
P1 = Process(target=Timer, args=(10,))
P1.start()
P2 = Process(target=Wait, args=(11,))
P2.start()
你会开始看到你想要的方向。
看看区别:这里我使用的是函数名(按惯例可以是小写,顺便说一句),没有立即"打开括号"在名字之后。 Python中的变量或函数名后面的括号表示同步对象调用(在本例中为函数调用)。在没有括号的情况下使用相同的名称会将该函数作为您正在创建的Process对象的参数传递。参数在args
参数中分开传递。
但除此之外,多处理根本不适用于全局变量 - 正如名称所示,每个函数都在不同的进程中运行,并且有自己的一组全局变量。)
相反,您必须做一些更复杂的事情,并使用(多处理)队列作为子进程中每个入口点的参数传递,以协调并行代码的操作。
查看https://docs.python.org/2/library/multiprocessing.html#pipes-and-queues
上的文档