【发布时间】:2020-06-12 03:02:45
【问题描述】:
我正在尝试与我在其中启动的其他进程共享类实例/对象变量,因为我需要同时运行多个函数,以从键盘和鼠标记录宏并在以后重新播放它们同一时间。
我发现可以使用 multiprocessing.Manager,但我使用的是 concurrent.futures.ThreadPoolExecutor。有没有类似的功能?
我现在写了下面的代码来澄清一下。实际代码中有一个 setState 函数用于设置录制状态等,并且按下的键不会被传递。此外,实际代码显然有一个按键和鼠标移动的侦听器,getKey 和 getMove 函数应该是附加到列表的函数。在这种情况下的问题是,一旦按下“插入”键,就不能从应该开始记录移动的第二个进程访问记录变量。一个类似于多处理中的管理器的并发函数可以解决它,但我不确定它被称为什么或使用它。
from concurrent.futures import ThreadPoolExecutor as Executor
import time
class recMacros(object):
def __init__(self):
self.recording = False
self.lastKey = None
self.lastMove = None
self.mouseMoves = []
self.keyPresses = []
self.runMacros()
def getTime(self):
return time.time()
def getKey(self):
#return keyboard listener last key pressed
return "W"
def getMove(self):
#return keyboard listener last key pressed
return "W"
def recMoves(self):
while True:
while self.recording:
mouseMove = self.getMove()
if mouseMove != self.lastMove:
self.mouseMoves.append((mouseMove, self.getTime()))
self.lastMove = mouseMove
def recPresses(self):
while True:
keyPress = self.getKey()
if keyPress == "Insert":
self.recording = True
elif keyPress == "End":
self.recording = False
elif self.recording and keyPress != self.lastKey:
self.keyPresses.append((keyPress, self.getTime()))
self.lastKey = keyPress
else:
print("Error")
def recMacros(self):
with Executor(max_workers=2) as e:
e.submit(recPresses)
e.submit(recMoves)
if __name__ == "__main__":
recMacros()
我很感激一些快速的方向,因为我很着急。提前致谢
@user2357112 支持莫妮卡 这是我用来测试时间的代码,以验证 ThreadPoolExecutor 就像一个进程来并行运行函数:
from concurrent.futures import ThreadPoolExecutor
import time
def printTime():
print(f"Time: {time.time()}\n")
def runPro():
with ThreadPoolExecutor(max_workers=3) as e:
for i in range(3):
e.submit(printTime)
runPro()
【问题讨论】:
-
concurrent.futures.ThreadPoolExecutor不是多处理。区别非常重要 - 尽管multiprocessing试图使其界面看起来像threading,但使用单独进程的行为与使用线程的行为非常不同。 -
谢谢。我确实怀疑它是一个多线程库而不是多处理库,但是当我测试它时,多个函数同时运行,这正是我所需要的。无论如何,当我测试它时,变量没有被共享,这意味着地址空间不同,就像它是一个进程一样。像管理这样的解决方案将不胜感激,我的日程安排很紧。我将我用来测试时间的代码添加到线程中,因为它使评论超出限制,无法在这里添加。
-
不,
ThreadPoolExecutor不对地址空间做任何事情。如果看起来你有一个单独的地址空间,那么你真正拥有的是一个错误。 -
有道理,它被称为“ThreadPoolExecutor”是有原因的。需要明确的是,变量值不会在其他线程中更新,这可能是什么错误?我将 self.recording 的等效值更新为 False 并且它没有改变。
-
我们无法确定,因为您发布的代码不会重现问题。 (您发布的代码因完全不同的原因而失败。)如果我们有 minimal reproducible example,我们也许能够识别出错误。
标签: python parallel-processing macros multiprocessing concurrent.futures