如何确保Python线程在目标函数完成后终止?

2 投票
1 回答
1258 浏览
提问于 2025-04-17 04:29

我有一个服务,它会启动一些线程。
这些线程是通过提供一个目标函数来启动的。
看起来当这个函数结束时,线程并没有“死掉”。我知道这一点是因为线程会通过Paramiko(通过Fabric)进行一些SSH连接,如果我用lsof命令查看,就会发现这些SSH连接在函数完成后仍然是活跃的。
我该如何确保当目标函数完成时,线程也能结束呢?

这是我正在处理的一个例子:

from time import sleep
from threading import Thread
from fabric.api import run, settings

def thread_func(host):
    with settings(host_string=host):
        run('ls -lht /tmp')

def spawn_thread(host):
    t = Thread(
        target=thread_func,
        args=(host,)
    )
    t.start()

spawn_thread('node1.example.com')
while True:
    sleep(1)

如果我在另一个终端运行sudo lsof | grep ssh,而上面的代码还在无限循环中,我会看到以下内容,即使我知道这个线程应该不再存在:

python    6924      daharon    3u     IPv4             170520        0t0        TCP 10.1.1.173:47368->node1.example.com:ssh (ESTABLISHED)
python    6924      daharon    5u     IPv4             170524        0t0        TCP 10.1.1.173:47369->node1.example.com:ssh (ESTABLISHED)
python    6924 6930 daharon    3u     IPv4             170520        0t0        TCP 10.1.1.173:47368->node1.example.com:ssh (ESTABLISHED)
python    6924 6930 daharon    5u     IPv4             170524        0t0        TCP 10.1.1.173:47369->node1.example.com:ssh (ESTABLISHED)
python    6924 6932 daharon    3u     IPv4             170520        0t0        TCP 10.1.1.173:47368->node1.example.com:ssh (ESTABLISHED)
python    6924 6932 daharon    5u     IPv4             170524        0t0        TCP 10.1.1.173:47369->node1.example.com:ssh (ESTABLISHED)

1 个回答

2

你确定你的Fabric模块在执行ls命令时只进行了一次ssh连接吗?也就是说,它应该做的事情是:

ssh host ls -lht /tmp

这个命令会打开一个远程的命令行,运行ls -lht命令,然后再关闭连接。

但我怀疑Fabric库可能在做的事情是:

ssh host

host$ ls -lht /tmp

当然,它并没有提供一个真正的终端,但有一些ssh选项可以让你在没有交互式终端的情况下保持连接。这在某些情况下是很有用的(比如,如果你在同一台主机上运行很多命令,这种方法会重用现有的ssh会话,而不是每次都打开新的会话)。你可以查看文档,了解如何启用或禁用这种会话缓存的参数。

撰写回答