Python多线程/进程问题:线程未生效且需避免重复读取文件行
问题分析与解决方案
你的代码核心问题有两个:
- 进程完全没参与任务处理:当前只有
dostuff线程在逐个读取账号并打印,还加了sleep(1),这就是每秒只输出一个的原因。而你开的10个进程只是在等待队列里的"DONE"标记,根本没处理任何账号任务。 - 任务分发逻辑错误:没有把账号数据放到队列中交给进程处理,反而在读取线程里直接完成了所有输出操作。
另外,避免多线程/进程重复读行的关键是:只用一个生产者(线程/进程)负责读取文件并将账号数据放入队列,多个消费者(进程/线程)从队列取数据处理,这样就不会出现重复读取同一行的情况。
修改后的代码
from multiprocessing import Queue, Process from threading import Thread from time import sleep max_process = 10 # 用于存放账号任务的队列 task_queue = Queue() def produce_accounts(): # 生产者:读取账号文件,将每个账号数据放入队列 with open('acc.txt', 'r') as accounts: for line in accounts: line = line.strip() # 注意这里要赋值,原代码没接收strip的返回值 if not line: continue # 跳过空行 split = line.split(":") # 确保每行格式正确,避免索引报错 if len(split) != 3: print(f"无效账号行:{line}") continue account = { 'user': split[0], 'pass': split[1], 'name': split[2].replace('\n', ''), } task_queue.put(account) # 所有账号放入队列后,放入对应数量的DONE标记,通知进程退出 for _ in range(max_process): task_queue.put("DONE") def process_account(): # 消费者:从队列取账号,执行登录等任务 while True: item = task_queue.get() if item == "DONE": break # 模拟登录操作,这里替换成实际的登录逻辑 print(f"处理账号:{item}") sleep(1) # 模拟登录耗时 def main(): # 先启动所有工作进程 procs = [] for _ in range(max_process): p = Process(target=process_account) procs.append(p) p.start() # 启动生产者线程读取账号 producer_thread = Thread(target=produce_accounts) producer_thread.start() # 等待生产者完成所有账号的读取和入队 producer_thread.join() # 等待所有工作进程完成任务 for p in procs: p.join() print('所有任务完成') if __name__ == '__main__': main()
关键修改点说明
- 拆分生产者与消费者:
produce_accounts只负责读文件和往队列塞任务,process_account负责处理任务,分工明确。 - 修复字符串处理问题:原代码
account.strip()没有赋值,等于没做处理,修改为line = line.strip()。 - 增加格式校验:避免因账号行格式错误导致索引越界报错。
- 调整启动顺序:先开进程再启动生产者,确保进程能及时处理队列中的任务,不会出现任务堆积后才启动进程的情况。
- 队列任务分发:每个进程从队列取唯一的账号任务,自然避免了重复读取同一行的问题。
内容的提问来源于stack exchange,提问作者john lewis
相关产品推荐
相关产品推荐

