You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:52:04