我试图通过运行一些示例来围绕Python多线程,这是我不太了解的行为
#!python3.6
import threading
import time
class ThreadClass():
def __init__(self):
self.thread = threading.Thread(target=self.callback)
self.thread.start()
def __del__(self):
print("DESTROYED")
def callback(self):
print("start second thread")
print("second threadId=", threading.get_ident())
print("self memory=", id(self))
time.sleep(2)
print("stop second thread")
def run():
print("start first thread")
print("first threadId=", threading.get_ident())
thread = ThreadClass()
print("threadClass memory=",id(thread))
print("stop first thread")
run()
print("end")
我得到的输出是:
start first thread
first threadId= 140301467088640
start second thread
second threadId= 140301462193920
self memory= 140301465746680
threadClass memory= 140301465746680
stop first thread
end
stop second thread
DESTROYED
我不明白的是为什么run()函数结束后ThreadClass实例不被销毁。我的理解是ThreadClass的实例位于run()的堆栈上,所以当run()结束时,是否应该清除其堆栈并删除实例?但是不知何故,该ThreadClass的相同实例仍然有效,直到用它完成内存中其他地方的另一个线程为止。
换句话说,Python如何在线程之间共享内存?
答案 0 :(得分:2)
运行中的线程(及其对象)永远不会被垃圾回收(守护进程线程可能会终止其进程,但那是另外一回事)。
第二个线程的运行线程对象(存储在thread
实例的ThreadClass
中)引用了callback
实例的ThreadClass
方法(因为此方法在线程),因此在线程运行时需要实例。
变量仅包含对对象的引用,而不包含对象本身。仅当不再存在对对象的引用(弱引用除外)时,才可以对其进行垃圾回收。
在run()
的末尾,仅从堆栈中删除了一个引用。
答案 1 :(得分:0)
注意:def run()
与您的代码相同,与类ThreadClass 不相关。检查您的缩进,注意run
是在类之外的模块级别定义的。
按原样在代码中启动第二个线程,而不必等待它完成。因此,正常程序(run()
原样运行)到最后,而(第二个)线程仍在运行。对此没什么奇怪的,这就是为什么要使用线程的原因。并行运行并异步运行。
此外,为了获得完整的响应,python不保证立即进行垃圾回收。如果不再引用变量,则没有任何东西可以立即释放内存,任何句柄等。 因此,线程可能不会停止存在(并正在运行),可能直到整个python环境完成为止。 例如放在Thread garbage collection中,模块线程将保留对线程的引用。