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

Python多线程批量发送POST请求重复执行问题的修复咨询

修复Python多线程批量处理文件时条目重复执行的问题

问题描述

我用Python多线程实现带文件的POST请求,批量处理file.txt中的内容(内容为1、2、3、4、5),计划启用8个线程,示例中写了3个继承Thread的类,用islice给各线程分配行范围,但运行后出现条目重复执行的情况(比如1、2、3多次返回success),希望每个条目仅执行一次(1-5各返回一次success),如何修复?

原代码

import requests
import requests as reqs
from threading import *
from itertools import islice
from requests.packages.urllib3.exceptions import InsecureRequestWarning

account = "file.txt"

loaded = len(open(account, encoding = "ISO-8859-1").readlines())

class check1(Thread):
    def run(self):
        with open(account) as lines:
            for lines in islice(lines, 0, loaded, 8):
                check(lines)


class check2(Thread):
    def run(self):
        with open(account) as lines:
            for lines in islice(lines, 1, loaded, 8):
                check(lines)


class check3(Thread):
    def run(self):
        with open(account) as lines:
            for lines in islice(lines, 2, loaded, 8):
                check(lines)

            
workers = [check1(), check2(), check3()]
for worker in workers:
    worker.start()
for worker in workers:
    worker.join()

文件内容(file.txt)

1
2
3
4
5

当前运行结果

1 success
1 success
2 success
3 success
2 success
3 success
etc

期望结果

1 success
2 success
3 success
4 success
5 success

问题原因

  1. 步长设置错误:给islice设置的步长是8,但当前只有3个线程,每个线程会循环取自己起始索引的行(比如线程0一直取第0行,线程1一直取第1行),导致重复执行。
  2. 线程类冗余:手动创建多个Thread子类的方式扩展性差,新增线程需要额外写类,容易出错。
  3. 多线程重复读文件:每个线程单独打开文件读取,既浪费资源,也可能因文件读取位置问题导致重复。

修复方案

修正后的代码

import requests
from threading import Thread
from itertools import islice
from requests.packages.urllib3.exceptions import InsecureRequestWarning

# 禁用不安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

account_file = "file.txt"

def check(line):
    # 替换为你的实际POST请求逻辑
    print(f"{line.strip()} success")

class CheckThread(Thread):
    def __init__(self, thread_idx, total_threads, lines):
        super().__init__()
        self.thread_idx = thread_idx
        self.total_threads = total_threads
        self.lines = lines

    def run(self):
        # 每个线程处理从自身索引开始、步长为总线程数的行,确保无重叠
        for line in islice(self.lines, self.thread_idx, None, self.total_threads):
            check(line)

if __name__ == "__main__":
    # 提前读取所有行并过滤空行,避免多线程重复打开文件
    with open(account_file, encoding="ISO-8859-1") as f:
        all_lines = [line for line in f if line.strip()]

    total_threads = 3  # 可修改为你计划的8个线程
    workers = []
    # 批量创建并启动线程
    for idx in range(total_threads):
        worker = CheckThread(idx, total_threads, all_lines)
        workers.append(worker)
        worker.start()

    # 等待所有线程执行完毕
    for worker in workers:
        worker.join()

改进说明

  • 通用线程类:CheckThread支持任意数量线程,无需手动创建多个子类,扩展性强。
  • 任务分配逻辑修正:使用islice(self.lines, self.thread_idx, None, self.total_threads),每个线程处理的行索引无重叠:
    • 线程0处理索引0、3、6...
    • 线程1处理索引1、4、7...
    • 线程2处理索引2、5、8...
  • 提前读取文件:仅读取一次文件并过滤空行,避免多线程重复IO操作,提升效率。
  • 代码简洁性:去除冗余的requests重复导入,规范变量命名。

验证结果

运行修正后的代码,会输出:

1 success
2 success
3 success
4 success
5 success

完全符合期望,每个条目仅执行一次。

内容的提问来源于stack exchange,提问作者bymechul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:15:59