使用Python的Process模块同时运行多个while循环时出现错误,寻求解决方法
使用Python的Process模块同时运行多个while循环时出现错误,寻求解决方法
嘿,作为编程新手能自己动手做锁屏程序已经很棒啦!咱们先看看你遇到的问题出在哪,再一步步解决它~
问题原因分析
首先你碰到的EOFError: EOF when reading a line,是因为多进程里的子进程没办法直接获取终端的输入。每个Process都是独立的进程,它们有自己的标准输入流,而终端的输入只能被主进程捕获,子进程调用input()的时候就会因为读不到内容而抛出这个错误。
另外还有个隐藏问题:你用了全局变量strike,但多进程里的全局变量是各自独立的副本——也就是说loop_redemption进程里修改的strike,和loop_main进程里的strike根本不是同一个变量,就算没报错,你的“错误次数随时间减少”的逻辑也不会生效哦。
解决方案:用线程替代多进程
针对你的需求,其实用**线程(threading模块)**比多进程更合适,因为线程共享同一个进程的内存空间,全局变量能真正共享,而且线程里可以正常使用input()。
这里给你修改后的代码:
import time import threading Password = 20051402 # 自定义密码 strike = 0 # 错误次数 stop_redemption = False # 用来控制倒计时线程停止的标志 def loop_redemption(): global strike, stop_redemption while not stop_redemption: while strike >= 1 and not stop_redemption: time.sleep(5) if not stop_redemption: # 防止停止标志已经触发后还修改strike strike -= 1 print(f"错误次数已减少,当前剩余:{strike}") def loop_main(): global strike, stop_redemption while True: if strike >= 3: # 超时倒计时 for time_passed in range(5): print(f"已超时,剩余 {5 - time_passed} 秒后可重试") time.sleep(1) strike = 0 # 超时后重置错误次数 password = int(input("请输入密码:")) if password == Password: stop_redemption = True # 停止倒计时线程 print("密码正确!祝你今天愉快~") break else: strike += 1 if strike == 1: print("还有2次机会,否则将超时") elif strike == 2: print("还有1次机会,否则将超时") if __name__ == '__main__': # 创建并启动倒计时线程 redemption_thread = threading.Thread(target=loop_redemption) redemption_thread.start() # 运行主逻辑 loop_main() # 等待倒计时线程结束 redemption_thread.join()
修改点说明:
- 用
threading.Thread代替multiprocessing.Process,线程共享全局变量,解决了数据不同步的问题 - 新增
stop_redemption标志,用来在密码正确时优雅停止倒计时线程 - 超时后自动重置
strike,更符合常见的锁屏逻辑 - 优化了打印信息的可读性,让用户更清楚当前状态
(可选)如果坚持用多进程的实现方式
如果只是想了解多进程的用法,这个场景也可以实现,但需要用共享内存变量传递strike的值,并且把输入逻辑放在主进程,子进程只负责倒计时修改共享变量。示例代码如下:
import time from multiprocessing import Process, Value Password = 20051402 def loop_redemption(strike): while True: with strike.get_lock(): # 加锁防止多进程同时修改共享变量 if strike.value >= 1: time.sleep(5) strike.value -= 1 print(f"错误次数已减少:{strike.value}") else: time.sleep(1) # 没错误时休眠,减少CPU占用 def loop_main(strike): while True: with strike.get_lock(): current_strike = strike.value if current_strike >= 3: for time_passed in range(5): print(f"已超时,剩余 {5 - time_passed} 秒") time.sleep(1) with strike.get_lock(): strike.value = 0 password = int(input("请输入密码:")) if password == Password: print("密码正确!") break else: with strike.get_lock(): strike.value += 1 current_strike = strike.value if current_strike == 1: print("还有2次机会") elif current_strike == 2: print("还有1次机会") if __name__ == '__main__': strike = Value('i', 0) # 创建整数型共享变量,初始值0 redemption_process = Process(target=loop_redemption, args=(strike,)) redemption_process.start() loop_main(strike) redemption_process.terminate() # 结束子进程
其实你的需求用线程就完全足够了,多进程更适合CPU密集型任务,而你的程序是IO密集型(等待输入、等待时间),线程更轻量也更简单。
备注:内容来源于stack exchange,提问作者Shearedsheep
相关产品推荐
相关产品推荐

