polusok
(Mykhailo Poliarush)
03.Май.2012 06:27:53
#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
(Pavlo Basiuk)
03.Май.2012 07:06:34
#2
а тебе надо поток убить или процесс который был стартанут из другого потока (thread-a) ?
polusok
(Mykhailo Poliarush)
03.Май.2012 07:51:16
#3
сорри не правильно написал, да процесс
просто я пробовал разные варианты убийства с потока и с процесса, и ничего не получилось
Pavlo
(Pavlo Basiuk)
03.Май.2012 07:55:05
#4
попробуй так (не уверен будет ли работать на вин 7 )
handle = subprocess.Popen("someprocess here", shell=False)
subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)
Вообще очень не советовал бы убивать потоки, а особенно если это сервер. Когда вы будете убивать поток, то совершенно не знаете в каком состоянии будет сервер и к каким последствиям это может привести. Гораздо лучше использовать например переменную которая бы дала потоку понять что нужно завершится и поток перешел в безопасное состояние после чего бы завершился.
Ну если же все же решите убивать поток, то я в Пайтоне использовал следующую конструкцию:
for iThreadNumber in range(len(aServerHosts)): if (Threads[iThreadNumber].is_alive()): Threads[iThreadNumber]._Thread__stop()
Она у меня убивает все живие на тот момент потоки. Как вы можете увидеть, то функция _Thread__stop() - приватная (поскольку начинается с подчеркивания), что значит что создатели Пайтона не совсем советуют её использовать напрямую, но все же это может быть для вас решением.
polusok
(Mykhailo Poliarush)
03.Май.2012 08:15:00
#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()
polusok
(Mykhailo Poliarush)
03.Май.2012 08:18:23
#7
убивать потоки это уже крайность и перебор разных вариантов, потому что задачу надо решить любым способом
понятно, что не хорошо убивать, а надо быть хорошо завершать через какой-то сигнал программе, и конечно, не хочется использовать внутрение методы
но к этому приходишь, когда стандартные методы не работают, потому надо искать разные варианты
и спасибо за код для остановки потоков.