在 Python 中杀死线程并释放内存
Killing Thread and releasing memory in Python
我正在终止线程,如下所示:Is there any way to kill a Thread in Python?
但我注意到,内存没有释放(gc.get_objects()
不断增长)。事实上,这些对象是列表、字典等,而不是文件。
有没有办法手动释放资源?
代码:
import ctypes
def terminate_thread(thread):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None
self.error = None
def run(self):
try:
self.result = myfun(*args, **kw) #run external resource and the interrupt it
except Exception as e:
self.error = e
c = MyThread()
c.start()
c.join(60) # wait a minute
counter = 0
if c.isAlive():
while c.isAlive():
time.sleep(0.1)
try:
terminate_thread(c) # how to release resources?
except:
break
counter += 1
if counter > 10: break
raise TimeoutException
输出示例:
print('Controlled objects: %s' % len(gc.get_objects()))
print ('Unreachable: %s' % gc.collect())
Controlled objects: 85084 #request 1, no timeout
Unreachable: 5640
Controlled objects: 171994 # request 2, timeout
Unreachable: 7221
好吧,毕竟这些垃圾我想你想要的是多处理模块,因为我相信你实际上可以在上面发送一个 sigkill
class MyThread:
def __init__(self):
self.result = None
self.error = None
def start(self):
self.proc = multiprocessing.Process(target=self.run)
self.proc.start()
def stop(self):
self.proc.send_signal(multiprocessing.SIG_KILL)
def run(self):
try:
self.result = myfun(*args, **kw) #run external resource and the interrupt it
except Exception as e:
self.error = e
然后你会调用 c.stop()
以使用 sig_kill 停止线程(粗略地说,其他东西应该对此做出适当的响应)
您甚至可以只使用内置 subprocess.Process.kill()
(请参阅文档 https://docs.python.org/2/library/subprocess.html#subprocess.Popen.send_signal)
写下你的问题##
(有没有办法手动释放资源?)
t = Thread(target=some_long_running_external_process)
t.start()
无法从 some_long_running_external_process
外部退出您的线程 (t
)
我正在终止线程,如下所示:Is there any way to kill a Thread in Python?
但我注意到,内存没有释放(gc.get_objects()
不断增长)。事实上,这些对象是列表、字典等,而不是文件。
有没有办法手动释放资源? 代码:
import ctypes
def terminate_thread(thread):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None
self.error = None
def run(self):
try:
self.result = myfun(*args, **kw) #run external resource and the interrupt it
except Exception as e:
self.error = e
c = MyThread()
c.start()
c.join(60) # wait a minute
counter = 0
if c.isAlive():
while c.isAlive():
time.sleep(0.1)
try:
terminate_thread(c) # how to release resources?
except:
break
counter += 1
if counter > 10: break
raise TimeoutException
输出示例:
print('Controlled objects: %s' % len(gc.get_objects()))
print ('Unreachable: %s' % gc.collect())
Controlled objects: 85084 #request 1, no timeout
Unreachable: 5640
Controlled objects: 171994 # request 2, timeout
Unreachable: 7221
好吧,毕竟这些垃圾我想你想要的是多处理模块,因为我相信你实际上可以在上面发送一个 sigkill
class MyThread:
def __init__(self):
self.result = None
self.error = None
def start(self):
self.proc = multiprocessing.Process(target=self.run)
self.proc.start()
def stop(self):
self.proc.send_signal(multiprocessing.SIG_KILL)
def run(self):
try:
self.result = myfun(*args, **kw) #run external resource and the interrupt it
except Exception as e:
self.error = e
然后你会调用 c.stop()
以使用 sig_kill 停止线程(粗略地说,其他东西应该对此做出适当的响应)
您甚至可以只使用内置 subprocess.Process.kill()
(请参阅文档 https://docs.python.org/2/library/subprocess.html#subprocess.Popen.send_signal)
写下你的问题##
(有没有办法手动释放资源?)
t = Thread(target=some_long_running_external_process)
t.start()
无法从 some_long_running_external_process
t
)