使用schedule与multiprocessing并发运行浏览器进程求助
问题分析与解决方案
原代码的核心问题
你当前代码的最大错误在于schedule.do()的传参逻辑:
schedule.every().day.at("06:00").do(n1.start())中,n1.start()是直接执行进程启动方法,程序一运行就会立刻启动所有进程,完全没触发定时调度的逻辑。- 退一步说,即使改成
do(n1.start),进程对象也只能被start()一次,下次调度时该进程已处于终止状态,无法再次启动。
修正后的基础方案
调整逻辑,每次调度时动态创建并启动进程,同时简化重复代码:
import schedule import time from multiprocessing import Process def Zipe(arg1, arg2, arg3): # 这里是你的Zipe函数实现 pass def start_zipe_process(args): p = Process(target=Zipe, args=args) p.start() p.join() # 可选:等待进程结束,避免产生僵尸进程 if __name__ == '__main__': # 整理所有需要执行的参数组 process_args = [ ("01", "01", 5), ("01", "05", 10), ("01", "11", 15), ("01", "16", 20), ("01", "21", 25), ("01", "26", 30), ("01", "31", 35), ("01", "36", 40), ("01", "41", 45), ("01", "46", 50) ] # 为每个参数组添加定时任务 for args in process_args: schedule.every().day.at("06:00").do(start_zipe_process, args) while True: schedule.run_pending() time.sleep(5)
更优替代方案
1. 用进程池控制并发数
如果50个进程同时启动会占用过多系统资源,建议用multiprocessing.Pool限制并发数量:
import schedule import time from multiprocessing import Pool def Zipe(arg1, arg2, arg3): # 你的Zipe函数实现 pass def run_all_tasks(): process_args = [ ("01", "01", 5), ("01", "05", 10), # ... 补充剩余参数组 ("01", "46", 50) ] # 限制同时运行的进程数,比如设为10 with Pool(10) as pool: pool.starmap(Zipe, process_args) if __name__ == '__main__': schedule.every().day.at("06:00").do(run_all_tasks) while True: schedule.run_pending() time.sleep(5)
2. 改用APScheduler替代schedule库
APScheduler功能更强大,支持多进程、任务持久化、多种触发器(日期、间隔、cron),比schedule更适配复杂定时任务场景:
from apscheduler.schedulers.blocking import BlockingScheduler from multiprocessing import Pool def Zipe(arg1, arg2, arg3): # 你的Zipe函数实现 pass def run_all_tasks(): process_args = [ ("01", "01", 5), ("01", "05", 10), # ... 补充剩余参数组 ("01", "46", 50) ] with Pool(10) as pool: pool.starmap(Zipe, process_args) if __name__ == '__main__': scheduler = BlockingScheduler() # 每天6点执行任务 scheduler.add_job(run_all_tasks, 'cron', hour=6) scheduler.start()
内容的提问来源于stack exchange,提问作者wikid
相关产品推荐
相关产品推荐

