繁体   English   中英

如何销毁threading.Lock()创建的锁定对象?

[英]how to destroy lock object created by threading.Lock()?

如何销毁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()

如何销毁dict ['b']中的锁定对象?

我将把这一部分放在前面,因为它可能是最重要的。

您是否有一些有意义的理由要重新签入dct['a']引用的锁定对象? 如果不这样做,那么……或者首先不要将其存储在字典中,或者当您知道不再关心它时,只需手动将其存储在del dct['a'] 这样做只会删除对您的字典所拥有的锁的引用 ,而不是对象本身。

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']

再次强调一下,仅仅是因为您从字典中del它,仅意味着您删除了对该对象的特定引用。 只有一旦所有线程退出,就不会有现存的引用,从而使gc实际上可以销毁该对象。

关于需要在主线程中实际保持“签入”状态的情况下该怎么做的更深入的讨论。


如何销毁dict ['b']中的锁定对象?

不要,至少不要手动-让python的gc为您做到这一点。 您需要上一级工作-管理您的引用

如果要保留Lock对象的集合,则使其成为weakref的集合。 Python的垃圾回收器通过执行引用计数和仅存储weakrefs来工作,您不会阻止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 ,或者甚至在使用ref计数以外的gc策略的python风格上运行代码。
  • 请注意,即使弱引用所指向的锁被GC了,您的字典中仍然有一个weakref对象。 即使陈旧的代码指向None ,如果您的程序寿命特别长,您仍然希望定期进行检查并清除它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM