簡體   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