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

Flask多线程站点标题抓取项目如何实现一次性终止所有线程

问题根因

你现有代码的终止标识仅在循环遍历域名的阶段检查,当程序已经进入get_title执行网络请求时,不会触发终止逻辑,必须等当前请求完全执行完毕、进入下一轮循环时才会检测到stop_threads为True,所以会出现要等当前任务跑完才会停的问题。
Python官方没有提供线程强制终止的API,强行杀线程可能会导致内存泄漏、资源不释放的问题,用multiprocessing确实可以解决这个问题,因为进程支持直接调用terminate()方法强制终止,不需要等待内部逻辑执行完成。


优化后的多进程版本代码
import requests, time
from bs4 import BeautifulSoup
from flask import Flask, render_template, request, redirect, url_for
import multiprocessing

# 存储所有工作进程的全局列表
process_list = []

def chunker_list(seq, size):
    return (seq[i::size] for i in range(size))

def get_domens_from_file(filename):
    with open(filename, 'r') as f:
        domens = f.readlines()
        return domens

def get_title(url):
    # 给请求加超时,避免单个请求卡住过久
    response = requests.get(url, timeout=10)
    soup = BeautifulSoup(response.text, 'html.parser')
    title = soup.find('title').text.replace('\n', '').replace('  ', '')
    return title

def start_work(domens):
    for domen in domens:
        title = get_title(domen.strip())
        print(title)
        time.sleep(1)

app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])
def main():
    global process_list

    if request.method == 'POST':
        index = request.form['index']
        if index == 'start':
            # 先清空之前的进程列表,避免重复终止
            process_list = []
            domens = get_domens_from_file('C:\\Users\\Admin\\Desktop\\domains.txt')
            domens_list = list(chunker_list(domens, 5))

            for domens in domens_list:
                p = multiprocessing.Process(target = start_work, args=(domens, ))
                p.start()
                process_list.append(p)

        if index == 'stop':
            # 遍历所有进程直接强制终止
            for p in process_list:
                if p.is_alive():
                    p.terminate()
                    p.join()
            process_list = []
            print('stop')

        return redirect(url_for('main'))

    return render_template('index.html')

if __name__ == '__main__':
    # 多进程场景必须关闭debug模式,否则自动重载会导致进程管理异常
    app.run(debug=False)

注意事项
  • 多进程场景下不要开启Flask的debug模式,debug模式的自动重载机制会导致进程实例重复生成,无法正常终止
  • 如果不想换多进程,也可以在线程版本里给requests.get加超时,同时把stop_threads改成threading.Event对象,检查的颗粒度更细,也能大幅降低终止延迟,只是无法做到立刻终止当前正在执行的请求
  • 全局变量的读写在多线程场景下建议加锁,避免多线程同时修改变量出现可见性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:24:03