如何销毁由threading.Lock()创建的锁对象?例如,
import time
from threading import Thread
import threading
dict = {}
dict['a']=threading.Lock()
dict['b']=threading.Lock()
def myfunc(group, i, lck):
with lck:
print "group %s sleeping 5 sec from thread %d" % (group, i)
time.sleep(5)
print "finished sleeping from thread %d" % i
for i in range(5):
t = Thread(target=myfunc, args=('a', i, dict['a']))
t.start()
for i in range(5):
t = Thread(target=myfunc, args=('b', i, dict['b']))
t.start()
如何销毁断块中的锁对象?
发布于 2014-09-06 13:29:18
我会把这部分移到最前面,因为这可能是最重要的。
您有什么有意义的理由要签回dct['a']
引用的锁对象吗?如果你不那么做.然后,要么在一开始就不要将它存储在dict中,要么在您知道不再关心它的情况下只需要手动del dct['a']
。这样做只会删除对dict持有的锁的引用,而不是对象本身。
for i in range(5):
t = Thread(target=myfunc, args=('a', i, dct['a']))
t.start()
# some more operations that use dct['a'] would probably happen here,
# else why did we put it there in the first place...
del dct['a']
再次强调一下,仅仅因为您将其从本词典中删除,就意味着您删除了对对象的特定引用。只有当所有线程退出时,才会没有现存的引用,允许gc实际销毁对象。
如果您需要在主线程中继续对这个锁对象进行“签入”,那么应该做些什么呢?
我如何销毁断“b”中的锁定对象?
不要,至少不要手动-让python的gc为您这样做。你需要更高级别的工作--管理你的参考资料。
如果您希望将Lock
对象的集合保存在一起,请将其设置为weakref
的集合。Python的垃圾收集器通过执行引用计数来工作,并且仅通过存储弱引用,您不会阻止gc执行它的任务。示例:
import time
from threading import Thread
import threading
import weakref
dct = {}
def myfunc(group, i, lck):
if callable(lck):
#lck is a weakref, get the actual lock from it
lck = lck()
with lck:
print "group %s sleeping 5 sec from thread %d" % (group, i)
time.sleep(5)
print "finished sleeping from thread %d" % i
for i in range(5):
lock = dct.get('a', threading.Lock())
t = Thread(target=myfunc, args=('a', i, lock))
if 'a' not in dct:
dct['a'] = weakref.ref(lock)
t.start()
while dct['a']():
print 'lock still alive'
time.sleep(3)
print 'lock is dead, jim'
产出:
ben@nixbox:~$ python threadtest.py
group a sleeping 5 sec from thread 0
lock still alive
lock still alive
finished sleeping from thread 0
group a sleeping 5 sec from thread 1
lock still alive
...
lock still alive
finished sleeping from thread 4
lock is dead, jim
一旦Lock
不再被任何线程引用(强),它就会被垃圾收集(立即,在cpython中,可能稍后在其他python实现中)。一些注意事项:
dict
起名字。遮住了内置的东西。sleep(5)
,这是一个没有问题的问题,但对于非常短暂的线程,可能需要更复杂的参考管理策略。while dct['a']():
块看起来类似于join()
调用,但实际上并不依赖GC行为来管理程序控制。人们可以处理gc
,甚至可以在使用gc策略(而不是重新计算)的python上运行代码。weakref
对象在您的dict中。即使陈旧的程序只是指向None
,如果您的程序使用时间特别长,您仍然希望定期检查并清除它们。https://stackoverflow.com/questions/25700258
复制相似问题