我正在尝试创建一个简单的回调,它可以从另一个线程注册到一个对象。在本例中,调用回调的初始对象在它自己的线程上运行。在
下面的例子最好地说明了这一点:
from pprint import pprint
import sys
import weakref
import threading
import time
class DummyController(object):
def __init__(self):
self.name = "fortytwo"
def callback(self):
print("I am number : " + self.name)
class SomeThread(threading.Thread):
def __init__(self, listener):
threading.Thread.__init__(self)
self.listener = listener
def run(self):
time.sleep(1)
dummy = DummyController()
self.listener.register_callback(dummy.callback)
time.sleep(5)
del dummy
class Listener(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.runner = weakref.WeakMethod(self.default_callback)
self.counter = 20
def default_callback(self):
print("Not implemented")
def register_callback(self, function):
self.runner = weakref.WeakMethod(function)
def run(self):
while self.counter:
try:
self.runner()()
except Exception as e:
pprint(e)
self.counter -= 1
time.sleep(1)
listen = Listener()
some = SomeThread(listen)
listen.start()
some.start()
现在上面的代码可以正常工作了。但我担心这里的线程安全。通读weakref docs,我们不太清楚weakref是否真的是线程安全的,除了下面这行:
Changed in version 3.2: Added support for thread.lock, threading.Lock, and code objects.
我可能根本没看错。我需要添加锁吗,还是所有的东西都是线程安全的?在
非常感谢
好吧,我明白。这不是线程安全的问题,而是
weak reference
的问题。在有一个可执行的示例:
输出:
^{pr2}$如果显式调用
gc.collect()
,callback
将丢失其最后一个强引用,然后变成None
。由于您永远不知道gc
何时收集垃圾,因此存在一个潜在的问题。在不管您是否使用thread,它只是
weak reference
的正常行为。在顺便说一句,注意退出}移动到
SomeThread.run
也会隐式地del dummy
,您可以通过移除del dummy
并将{try
块来测试它。在相关问题 更多 >
编程相关推荐