我目前正在练习python多线程模块,我编写了一些如下代码,但它并没有像我期望的那样工作。
import threading
import thread
import random
import time
lock = threading.RLock()
def func(lock):
print("In Thread " + threading.currentThread().getName())
lock.acquire()
time.sleep(random.random()*10)
lock.release()
print("Out Thread " + threading.currentThread().getName())
def start():
lock.acquire()
for i in range(5):
thread.start_new(func, (lock,))
lock.release()
# for i in range(5):
# thread.start_new(func, (lock,))
start()
print("test")
time.sleep(1)
lock.acquire()
print("main ends")
lock.release()
在我看来,主线程中是否有time.sleep(1)对于新线程的运行并不重要,因为锁是全局的并且属于主线程,lock.acquire()操作会总是工作正常,所以主线程不应该等待那些新线程继续。根据thread.start_new()的属性,当主线程结束时,所有新线程也将停止。但是,当我注释掉time.sleep()行时,程序按照我的预期进行,但是当我添加此行时,主线程总是等待新线程完成。
这让我很困惑,并希望有人会向我解释Rlock()的功能,以及当我在主线程中创建它同时将其传递给子新线程并调用lock时它属于哪个线程.acquire()?
答案 0 :(得分:1)
一个锁属于最后成功执行.acquire()
的线程,直到它.release()
为止。
RLock
,可重入锁定的简称是一个锁,可以通过最初获取它的同一个线程多次获取;锁保持锁定并由线程保持,直到每次采集都被释放。
re-entrancy在这里意味着执行进入由锁保护的代码段,而锁已经存在。您的代码不会演示需要重入锁定但假设您具有函数的情况:
def guarded_op():
with lock:
print("Now doing 1 op")
another_op()
def another_op():
with lock:
print("Now did the another op")
一个不可重入的锁在那里不起作用,因为“锁定已被锁定”在守卫的操作中;锁定在another_op
中失败;但RLock
效果很好。
顺便说一句,你应该尽可能使用带有锁的with
语句来确保它们的有序释放。