简体   繁体   中英

How to kill a process within a thread in python?

Ok, Class A is the Thread. Class B does the call. I tried to kill more than one process (tor, and a firefox) created inside the thread but seems that signals can only be send throught the main thread, so it failed, It says:

signal only works in main thread

I don't really understand threads well...

import subprocess
from threading import Thread

class A(Thread):

    def __init__(self):
        Thread.__init__(self)

    def run(self):
        # CREATE TWO PROCESSES
        subprocess.call(['tor'], shell=True)
        subprocess.call(['firefox'], shell=True)

        # ... stuff to get the pid of each process ...

        # KILL'EM (the failing part)
        subprocess.call(['kill -9 5431'], shell=True)
        subprocess.call(['kill -9 5432')], shell=True)

class B(object):
    def __init__(self):
        x = A()
        x.start()

if __name__ == '__main__':
    B()

I don't know if it could be done with an RLock. Acquire, then call the subprocess.call with the signal and release to continue with the thread execution... Or if there's a better solution. Any help would be greatly appreciated !!

You can kill processes you created by using the terminate (graceful) and kill methods of the Popen object. Some programs like firefox tend to return immediately, so this doesn't always work. But the general idea is:

import subprocess
import threading

def kill_this(procs, hard=False):
    """kill the Popen processes in the list"""

    for proc in procs:
        if hard:
            proc.kill()
        else:
            proc.terminate()

class A(threading.Thread):
    """Runs tor and firefox, with graceful termination in 10 seconds and
    a hard kill in 20 seconds as needed"""

    def __init__(self):
        Thread.__init__(self)

    def run(self):
        # create processes
        tor = subprocess.Popen(['tor'])
        firefox = subprocess.Popen(['firefox'])

        # setup timers to kill 'em 
        soft = threading.Timer(10, kill_this, ((tor, firefox), False))
        hard = threading.Timer(20, kill_this, ((tor, firefox), True))

        # wait for process exit
        tor.wait()
        firefox.wait()

        soft.cancel()
        hard.cancel()

Alternately, you can use system calls to get the pid of the process you want to kill and then convert kill_this to use a different API:

import subprocess
import threading
import signal

def kill_this(procs, hard=False):
    """kill the process pids in the list"""

    for proc in procs:
        if hard:
            os.kill(pid, signal.SIGKILL)
        else:
            proc.terminate(pid, signal.SIGTERM)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM