函数内调用multiprocess时进程异常重启的问题求助
问题描述
调用multiProcessCharacters函数,预期为3个角色各创建3个进程并行检测3种特质以提升速度(原单线程版本正常但效率低)。程序需通过按下t键循环切换角色完成检测,但实际运行时,进程“结束”后会从Python代码开头重启,无法正常执行。
核心代码
批量选择要检测的角色
character = [['1',False],['2',False],['3',False]] user = '' while user!='n': user=input("Did you want to not roll any characters?\nEnter: 1/2/3/n\n1=Character One\n2=Character Two\n3=Character Three\n=n=no\n") if user=='1': character[0][1]=True elif user=='2': character[1][1]=True elif user=='3': character[2][1]=True elif user=='n': print("Character rolling will start in 10 seconds!\n") else: print("Not a proper input")
特质检测主循环
while mainTraits[0][1]==False or mainTraits[1][1]==False or mainTraits[2][1]==False: time.sleep(10) print("Character rolling starts now!\n") print("Rolling for:\nUnbreakable\nCooking\nIncredible Immune System\n") for i in range(3): if character[i][1] == False: print(f"Starting character {i+1}") whichTrait = multiProcessCharacters(mainTraits,secondaryTraits,character[i][0]) print(f"Character {i+1} Done!\n") if whichTrait == '1': mainTraits[0][1]=True elif whichTrait == '2': mainTraits[1][1]=True elif whichTrait == '3': mainTraits[2][1]=True character[i][1] = True # 修复原代码的==赋值错误 user=input("Are you happy with these characters? y/n\n") if user=='n': traitChosen=False characterChosen=False while characterChosen==False: characterChoice=input("Which character would you like to reroll? 1/2/3\n") if characterChoice=='1': character[0][1]=False characterChosen=True elif characterChoice=='2': character[1][1]=False characterChosen=True elif characterChoice=='3': character[2][1]=False characterChosen=True while characterChosen==True and traitChosen==False: traitChoice=input("Which trait would you like to reroll?\nUB\nCook\nISS") if traitChoice=="UB": mainTraits[0][1]=False traitChosen=True elif traitChoice=="Cook": mainTraits[2][1]=False traitChosen=True elif traitChoice=="ISS": mainTraits[1][1]=False traitChosen=True
检查角色是否拥有三种特质
def checkIfThreeTraits(characterLeft, characterRight): tripleTraitList=list(pyautogui.locateAllOnScreen(tripleTrait, grayscale=True, confidence=0.9)) for trait_loc in tripleTraitList: if characterLeft < trait_loc.left < characterRight: return True return False
检测次要特质
def loopSecondaryTraits(mainTraitLoc, character, traits, characterLeft, characterRight): print("Checking secondary stuff\n") for trait in traits: traitLoc=pyautogui.locateOnScreen(trait, grayscale=True, confidence=0.9) if traitLoc is not None: if characterLeft < traitLoc.left < characterRight and traitLoc != mainTraitLoc: if checkIfThreeTraits(characterLeft, characterRight): # 修复参数缺失问题 return True return False
主特质搜索函数
def searchMainTrait(trait, secondaryTraits, character): if character=='1': characterLeft = characterOneLeft characterRight = characterOneRight elif character=='2': characterLeft = characterTwoLeft characterRight = characterTwoRight elif character=='3': characterLeft = characterThreeLeft characterRight = characterThreeRight else: print("Character doesn't exist") exit(0) traitlocOne=pyautogui.locateOnScreen(trait, grayscale=True, confidence=0.9) if traitlocOne is not None: if characterLeft < traitlocOne.left < characterRight: # 补全loopSecondaryTraits的缺失参数 found=loopSecondaryTraits(traitlocOne, character, secondaryTraits, characterLeft, characterRight) if found: return True return False
多进程检测函数
def multiProcessCharacters(mainTraits, secondaryTraits, character): traitOne = mainTraits[0][0] traitTwo = mainTraits[1][0] traitThree = mainTraits[2][0] if character=='1': pyautogui.moveTo(characterOneMousePosition) elif character=='2': pyautogui.moveTo(characterTwoMousePosition) elif character=='3': pyautogui.moveTo(characterThreeMousePosition) else: print("Character doesn't exist") exit(0) while not (mainTraits[0][1] and mainTraits[1][1] and mainTraits[2][1]): futures = [] with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor: if not mainTraits[0][1]: print("Process 1 starting") futures.append(('1', executor.submit(searchMainTrait, traitOne, secondaryTraits, character))) if not mainTraits[1][1]: print("Process 2 starting") futures.append(('2', executor.submit(searchMainTrait, traitTwo, secondaryTraits, character))) if not mainTraits[2][1]: print("Process 3 starting") futures.append(('3', executor.submit(searchMainTrait, traitThree, secondaryTraits, character))) # 优先处理第一个完成的检测任务 for trait_id, future in concurrent.futures.as_completed(futures): if future.result(): print(f"Pair {trait_id} Done!\n") return trait_id pyautogui.press(['t'])
问题原因及修复方案
1. 多进程导致主模块代码重复执行(核心重启问题)
Windows系统中,multiprocessing创建子进程时会重新导入主模块,导致主模块顶层代码(如角色选择循环)被子进程重复执行,表现为程序“重启”。
修复:
将所有主程序逻辑放入if __name__ == '__main__':块中,避免子进程执行顶层代码:
if __name__ == '__main__': # 初始化全局变量 mainTraits = [['unbreakable.png', False], ['cooking.png', False], ['immune.png', False]] secondaryTraits = ['trait1.png', 'trait2.png'] characterOneLeft, characterOneRight = 100, 300 # 其他全局变量定义... # 批量选择角色、特质检测主循环等代码全部放入此处
2. 变量赋值/引用错误
- 原代码中
character[i][1] == True是比较操作,需改为character[i][1] = True完成赋值。 multiProcessCharacters中原t1Found等变量是复制值,无法同步主进程状态,直接使用mainTraits的状态判断即可。
3. 函数参数错误
loopSecondaryTraits调用checkIfThreeTraits时缺失参数,且自身被调用时也缺少characterLeft和characterRight参数,需补全对应参数传递。
4. 进程池使用问题
- 原代码中未定义的
f1/f2/f3会导致报错,改用列表存储提交的任务,通过as_completed优先处理完成的任务,提升效率同时避免报错。
内容的提问来源于stack exchange,提问作者ESRainbowWolf
相关产品推荐
相关产品推荐

