这里先说一下加锁的机制,其是如何实现线程保护的。这个实现的大致过程为:首先在需要同步的代码块前面加上lock.acquire()语句,表示需要先成功获取该锁,才能继续执行下面的代码,然后在需要同步的代码块后面加上lock.release()语句,表示释放该锁。所以,如果当一个线程或进程获取该锁,而且该锁没有被释放的话,那么其他的线程或进程是无法成功获取该锁的,从而也就没法执行下面的同步代码块,从而起到保护作用,直至释放该锁,其他的线程或进程才可以成功获取该锁,然后继续执行下面的代码块。通过上述,一个明显的基本前提是,不同线程或进程面对的锁必须是同一把锁,即同步代码块前后的lock对象必须是同一个,不然如果每个线程或进程有自己不同的锁,那么这个锁也就自然起不到保护作用。
这里可以看一下我昨天写的一个demo
#@Time : 2020-12-07
#@Author : LBOcean
"""
进程:正在运行的程序
线程:cpu调度的单位,一个进程可以包含多个线程
多线程: 合适IO密集型
多进程: cpu密集型任务
"""
import threading
import time
def my_print(name):
for i in range(10):
time.sleep(1)休息一秒在进行下一个循环
print(name,i)
start = time.time()#返回当前的时间戳
t1 = threading.Thread(target = my_print,args = ["threading1:"]) #传个任务,和参数进来
t2 = threading.Thread(target = my_print,args = ['threading2:'])
t1.start()#线程开始
t2.start()
t1.join()
t2.join()
end = time.time()
print(end-start)
print("结束")
这里运行出来的结果:是如下的。
这里是没有加锁的情况:
可以看见,在输出threading1:1 和threading2:1的时候切换了线程。
当要输出1的时候切换到输出threading2了。
如何避免这种情况发生,就要用到线程锁了。
先来介绍一下:
lock.acquire() :
获取锁,阻塞或非阻塞,当阻塞参数值为True(默认)时,为阻塞状态,锁为非锁定状态时变为非阻塞状态.,设定为锁定,立即返回;blocking为False时,不阻塞,当blocking设定为True时,线程锁定,返回False,锁定时返回True
lock.release() :
释放锁,任意线程均可调用,不局限于有lock的线程
上代码
#@Time : 2020-12-07
#@Author : LBOcean
#name : Mashine_S
"""
进程:正在运行的程序
线程:cpu调度的单位,一个进程可以包含多个线程
多线程: 合适IO密集型
多进程: cpu密集型任务
"""
import threading
import time
lock = threading.RLock()
def my_print(name):
for i in range(10):
time.sleep(1)
lock.acquire()
print(name,i)
lock.release()
start = time.time()#返回当前的时间戳
t1 = threading.Thread(target = my_print,args = ["threading1:"]) #传个任务,和参数进来
t2 = threading.Thread(target = my_print,args = ['threading2:'])
t1.start()#线程开始
t2.start()
t1.join()
t2.join()
end = time.time()
print(end-start)
print("结束")
这里我们可以看到,并不会出现,还没有输出完,就切换线程了的情况