【发布时间】:2017-12-12 08:45:02
【问题描述】:
我正在尝试创建一个可以从另一个线程注册到对象的简单回调。在这种情况下,调用回调的初始对象在自己的线程上运行。
下面的例子可以很好地说明这一点:
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是否真的是线程安全的,除了这行:
3.2 版更改:添加了对 thread.lock、threading.Lock 和代码对象的支持。
我可能只是没有读对。我是否需要添加锁定,或者一切实际上都很好并且线程安全?
非常感谢
【问题讨论】:
-
文档意味着在 3.2 版本中,您可以对 thread.lock、threading.Lock 和代码对象进行弱引用,但并不意味着存在内部锁。而且我不明白哪个部分可能不安全?能举个例子解释一下吗?
-
我的担心来自
Listener运行对象函数的回调,但是另一个线程(SomeThread)然后删除了对象。因为它使用weakref.WeakMethod,所以对象应该立即从内存中删除,而不需要垃圾收集器的参与,所以我想知道如果删除回调函数对象时是否会导致竞争条件,如果对象被删除并且函数被调用同时。是不是清楚一点?
标签: python multithreading