I have a service that spawns threads.
The threads are started by providing a target function.
It would appear that the thread doesn’t “die” when the function ends. I know this because the thread makes some SSH connections with Paramiko (via Fabric), and if I do an lsof I see the SSH connections are still active after the function completes.
How can I make sure that a thread dies when its target function completes?
Here is an example of what I am working with:
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)
And if I run sudo lsof | grep ssh in another terminal while the above code is in its infinite loop I’ll see the following, even after I know that the thread should not exist anymore:
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)
Are you sure your fabric module is doing the ssh only for the duration of the ls command. That is, it should be doing the equivalent of
ssh host ls -lht /tmp
This commandline will open a remote shell to run the ls -lht command and then shutdown.
But I suspect the Fabric library might be doing the equivalent of:
ssh host
host$ ls -lht /tmp
.
.
Of course it’s not providing a real tty but there are different ssh options that allow keeping a connection open without an interactive tty. This would be desirable in certain cases (e.g., if you run lots of commands on the same host, this technique will reuse the existing ssh session instead of opening new session every time. Check the documentation for arguments to enable or disable such session caching.