首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何销毁由threading.Lock()创建的锁对象?

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

Stack Overflow用户
提问于 2014-09-06 12:29:03
回答 1查看 1.5K关注 0票数 0

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

代码语言:javascript
运行
复制
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()

如何销毁断块中的锁对象?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-06 13:29:18

我会把这部分移到最前面,因为这可能是最重要的。

您有什么有意义的理由要签回dct['a']引用的锁对象吗?如果你不那么做.然后,要么在一开始就不要将它存储在dict中,要么在您知道不再关心它的情况下只需要手动del dct['a']。这样做只会删除对dict持有的锁的引用,而不是对象本身。

代码语言:javascript
运行
复制
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执行它的任务。示例:

代码语言:javascript
运行
复制
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'

产出:

代码语言:javascript
运行
复制
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上运行代码。
  • 请注意,即使在弱引用的锁获得GC之后,您仍然有一个weakref对象在您的dict中。即使陈旧的程序只是指向None,如果您的程序使用时间特别长,您仍然希望定期检查并清除它们。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25700258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档