在 Python 中,当函数 check_Temp 退出或引发异常时,我们需要杀死主进程。虽然这种方式可能不是最佳方案,但由于需要集成大量代码,因此这是最简单的方法。我们想要强制关闭程序,即使在关闭程序后出现一些错误也无所谓。
我们尝试了 os.taskskill()、sys.exit()、os.exit() 等方法,但子进程无法杀死主进程。我们不介意所有 Python 进程都被杀死。但是,我们的公司 IT 部门阻止了对 psutil 的下载,因此我们想知道是否有其他解决方案。
以下是代码示例:
import threading
import time
import os
from subprocess import call
def check_Temp(temp, delay, run_event, pid):
while run_event.is_set():
##code for checking temperature will go here.
time.sleep(delay)
print("temp is %s \n" % temp)
temp = temp - 1
#print os.getpid()
if temp <= 38:
raise Exception('LowTemp')
#call('pkill python', shell=True)
os.popen('TASKKILL /PID ' + str(pid) + ' /F')
#os.killall()
#sys.exit() #want to exit main loop here
if __name__ == "__main__":
run_event = threading.Event()
run_event.set()
temp = 45
d1 = .1
#print os.getpid()
pid = os.getpid();
t1 = threading.Thread(target=check_Temp, args=(temp, d1, run_event, pid))
t1.start()
print("Starting")
########## main code will go here, just have a simple counter here to test the functionality.
x = 25
try:
while 1:
time.sleep(.1)
x = x - 1
print("x is %s \n" % x)
if x < 0:
print("x is %s" % x)
raise Exception('spam', 'eggs')
#exit()
except Exception as e:
print(e) # the exception instance
run_event.clear()
t1.join()
print("thread successfully closed")
输出结果如下:
Starting
temp is 45
x is 24
temp is 44
x is 23
temp is 43
x is 22
temp is 42
x is 21
temp is 41
x is 20
temp is 40
x is 19
temp is 39
x is 18
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python26\lib\threading.py", line 532, in __bootstrap_inner
self.run()
File "C:\Python26\lib\threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\PythonSv\multithread6.py", line 14, in check_Temp
raise Exception('LowTemp')
Exception: LowTemp
x is 17
x is 16
x is 15
x is 14
x is 13
x is 12
x is 11
x is 10
x is 9
x is 8
x is 7
x is 6
x is 5
x is 4
x is 3
x is 2
x is 1
x is 0
x is -1
x is -1
('spam', 'eggs')
thread successfully closed
2、解决方案
问题的关键在于使用标志和回调,而不是异常。
以下是改进后的代码示例:
import threading
import time
import os
from subprocess import call
def check_Temp(temp, delay, run_event, pid, endit):
while run_event.is_set():
time.sleep(delay)
##code for checking temperature will go here.
print("temp is %s \n" % temp)
temp = temp - 1
#print os.getpid()
if temp <= 38:
print('LowTemp %s!' % (temp, ))
endit()
run_event.clear()
if __name__ == "__main__":
run_ok = True
def Terminator():
global run_ok
print("Terminating")
run_ok = False
run_event = threading.Event()
run_event.set()
temp = 45
d1 = .1
#print os.getpid()
pid = os.getpid();
run_ok = True
t1 = threading.Thread(target=check_Temp, args=(temp, d1, run_event, pid, Terminator))
t1.start()
print("Starting")
########## main code will go here, just have a simple counter here to test the functionality.
x = 25
try:
while run_ok:
time.sleep(.1)
x = x - 1
print("x is %s " % x)
if x < 0:
print("x is %s" % x)
raise Exception('spam', 'eggs')
#exit()
t1.join()
print('Finished!')
使用这种方法,当 temp 等于或低于 38 时,线程将打印一条消息并调用 Terminator() 函数,该函数将清除运行事件并终止主线程。
以下是改进后的代码输出结果:
Starting
temp is 45
x is 24
temp is 44
x is 23
temp is 43
x is 22
temp is 42
x is 21
temp is 41
x is 20
temp is 40
x is 19
temp is 39
x is 18
LowTemp 38 !
Terminating
x is 17
x is 16
x is 15
x is 14
x is 13
x is 12
x is 11
x is 10
x is 9
x is 8
x is 7
x is 6
x is 5
x is 4
x is 3
x is 2
x is 1
x is 0
x is -1
x is -1
('spam', 'eggs')
Finished!
通过使用标志和回调,我们成功地解决了在子线程中杀死主线程的问题。