t.me/atinfo_chat Telegram группа по автоматизации тестирования

Как убить поток в Python?


(Mykhailo Poliarush) #1

Я реализовал определенную логику, которая должна запускаться как сервер на бекграунде.

Соответственно, потом надо этот потом убить. 

Вот тут и получаются проблемы. Стартануть можно без проблем, а завершить не так просто.

Перепробовал уже кучу способов и на Win7 пока, что у меня не получилось завершить поток.

пример кода1

my_process = subprocess.Popen(['c:\\run.cmd'])
print my_process.pid
pid = my_process.pid
time.sleep(5)
my_process.kill()
my_process.terminate()
import os
import signal
os.kill(pid,signal.SIGTERM)
 
 
пример кода2 с переопределением 
 
import threading
import time
import subprocess
import thread
class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""
 
    def __init__(self, *args,**kwargs):
        super(StoppableThread, self).__init__(*args,**kwargs)
        self._stop = threading.Event()
 
    def stop(self):
        self._stop.set()
 
    def stopped(self):
        return self._stop.isSet()
 
def f():
s = subprocess.Popen(['c:\\run.cmd'])
print s
s.kill()
 
#s = subprocess.Popen(['c:\\run.cmd'])
#time.sleep(5)
#s.kill()
#print "start"
#thread = StoppableThread(target=f)
##thread.setDaemon(True)
#thread.start()
#print thread.isDaemon()
#print thread.stopped()
#print "is thread alive %r" % thread.isAlive()
#time.sleep(5)
#thread.stop()
#print "is thread alive %r" % thread.isAlive()
#print thread.stopped()
#print "stop"
#time.sleep(5)
#print "is thread alive %r" % thread.isAlive()
#thread._Thread__stop()
#print "is thread alive %r" % thread.isAlive()
#time.sleep(5)
#print "thread name %r" % str(thread.getName())

 


(Pavlo Basiuk) #2

а тебе надо поток убить или процесс который был стартанут из другого потока (thread-a) ?

 


(Mykhailo Poliarush) #3

сорри не правильно написал, да процесс

просто я пробовал разные варианты убийства с потока и с процесса, и ничего не получилось

 


(Pavlo Basiuk) #4

попробуй так (не уверен будет ли работать на вин 7 )

 

handle = subprocess.Popen("someprocess here", shell=False)

subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)


(WhiteAngel) #5

Вообще очень не советовал бы убивать потоки, а особенно если это сервер. Когда вы будете убивать поток, то совершенно не знаете в каком состоянии будет сервер и к каким последствиям это может привести. Гораздо лучше использовать например переменную которая бы дала потоку понять что нужно завершится и поток перешел в безопасное состояние после чего бы завершился.

Ну если же все же решите убивать поток, то я в Пайтоне использовал следующую конструкцию:

for iThreadNumber in range(len(aServerHosts)):
            if (Threads[iThreadNumber].is_alive()):
                Threads[iThreadNumber]._Thread__stop()


Она у меня убивает все живие на тот момент потоки. Как вы можете увидеть, то функция _Thread__stop() - приватная (поскольку начинается с подчеркивания), что значит что создатели Пайтона не совсем советуют её использовать напрямую, но все же это может быть для вас решением.


(Mykhailo Poliarush) #6

да, спасибо так заработало. 

я еще все обернул в поток, так как мне нужно запускать приложение в фоне

 

import threading
import time
import subprocess
import thread
class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""
 
    def __init__(self, app_to_run, *args,**kwargs):
super(StoppableThread, self).__init__(*args,**kwargs)
self._stop = threading.Event()
self.handle = subprocess.Popen(app_to_run, shell=False)
 
    def stop(self):
subprocess.Popen("taskkill /F /T /PID %i"%self.handle.pid , shell=True)
self._stop.set()
 
 
    def stopped(self):
        return self._stop.isSet()
 
thread = StoppableThread("c:\\run.cmd")
thread.setDaemon(True)
thread.start()
time.sleep(5)
thread.stop()

(Mykhailo Poliarush) #7

убивать потоки это уже крайность и перебор разных вариантов, потому что задачу надо решить любым способом

понятно, что не хорошо убивать, а надо быть хорошо завершать через какой-то сигнал программе, и конечно, не хочется использовать внутрение методы

но к этому приходишь, когда стандартные методы не работают, потому надо искать разные варианты

 

и спасибо за код для остановки потоков.