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

如何通过线程内函数调用stop()终止基于Selenium与Threading的Python程序运行

问题分析

你现在的核心困扰很明确:后台线程里调用的stop()函数只是让线程自己陷入死循环,完全无法影响主线程的执行流程。因为线程共享进程空间,单个线程的死循环不会终止整个进程,主线程该跑还是跑。而且你的stop()函数本身设计就不对——它没有任何终止程序的逻辑,只是让调用它的线程卡住而已。

可行解决方案

方案1:使用线程Event实现优雅退出(最推荐)

这是最规范的方式,属于优雅终止,能让主线程主动检测退出信号,还可以在退出前做资源清理(比如关闭Selenium驱动、释放其他占用的资源)。

实现思路

  1. 定义一个threading.Event对象作为全局终止信号
  2. 修改check_browser_running函数,在检测到浏览器关闭时设置这个Event
  3. 主线程循环监听这个Event,一旦被触发就执行退出逻辑

代码示例

import threading
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
import sys

# 全局终止信号,初始为未触发状态
stop_event = threading.Event()

def check_browser_running(driver):
    while not stop_event.is_set():
        try:
            # 尝试获取页面标题,判断驱动是否存活
            _ = driver.title
        except WebDriverException:
            print("DRIVER WAS CLOSED")
            # 设置终止信号,通知主线程退出
            stop_event.set()
            break

def main():
    driver = webdriver.Chrome()
    # 启动检测线程,传入driver对象
    th = threading.Thread(target=check_browser_running, args=(driver,))
    th.daemon = True  # 设置为守护线程,主线程退出时自动终止该线程
    th.start()

    # 主线程的业务逻辑,这里用循环模拟你的实际代码
    while not stop_event.is_set():
        # 你的其他代码逻辑写在这里
        pass

    # 退出前的清理工作
    driver.quit()
    print("程序已正常终止")
    sys.exit(0)

if __name__ == "__main__":
    main()

方案2:直接终止整个进程(粗暴但高效)

如果你不需要优雅清理资源,只是想在浏览器关闭后立刻终止整个程序,可以在检测线程里直接调用os._exit()——注意:sys.exit()只会退出当前线程,无法终止主线程,而os._exit()会直接终止整个进程。

修改后的代码

import os
import threading
from selenium import webdriver
from selenium.common.exceptions import WebDriverException

def stop():
    # 直接终止整个进程,参数0表示正常退出
    os._exit(0)

def check_browser_running(driver):
    while True:
        try:
            _ = driver.title
        except WebDriverException:
            print("DRIVER WAS CLOSED")
            stop()
            break

# 主线程启动部分
driver = webdriver.Chrome()
th = threading.Thread(target=check_browser_running, args=(driver,))
th.start()

# 主线程业务逻辑
while True:
    # 你的实际代码逻辑
    pass

方案3:使用全局变量作为终止标志

和Event的思路类似,用一个全局布尔变量标记是否需要终止,主线程轮询这个变量来决定是否退出:

代码示例

import threading
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
import sys

# 全局终止标志
should_stop = False

def check_browser_running(driver):
    global should_stop
    while not should_stop:
        try:
            _ = driver.title
        except WebDriverException:
            print("DRIVER WAS CLOSED")
            should_stop = True
            break

def main():
    global should_stop
    driver = webdriver.Chrome()
    th = threading.Thread(target=check_browser_running, args=(driver,))
    th.daemon = True
    th.start()

    while not should_stop:
        # 主线程业务逻辑
        pass

    driver.quit()
    sys.exit(0)

if __name__ == "__main__":
    main()
关键注意点
  • 一定要抛弃原来的stop()函数,它完全起不到终止程序的作用,只会占用线程资源
  • 建议给检测线程设置daemon=True,这样主线程退出时,后台线程会自动被终止,避免残留僵尸线程
  • 优先选择方案1的优雅退出方式,能避免残留浏览器进程或未释放的资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 14:03:11