简介:
多线程中,当多个线程共享资源时候,不加锁,会造成资源的混乱,下面针对此问题演示一个Demo范例。
范例:
同时开启三个线程,这三个线程之间会相互抢占公共资源,会造成混乱。此Demo是按照学生选课的方式进行说明。
目前,学校开设了一门选修课语文课,语文课总共有两个名额,但是,有三名同学都选择语文课,最终肯定是有两名学生选上了,有一名学生落选了。
下面我们看看这个例子,加锁情况和不加锁情况的效果分别是怎么样的。
1.范例之没加锁代码Demo:
import threading import time def student1(): print("学生-1开始选择课程...") global course_person if course_person > 0: course_person -= 1 time.sleep(1) print("学生-1选择课程成功,现在剩余名额为%d"%course_person) else: time.sleep(1) print("学生-1选择课程失败,没有名额了,请选择其他科目") pass def student2(): print("学生-2开始选择课程...") global course_person if course_person > 0: course_person -= 1 time.sleep(1) print("学生-2选择课程成功,现在剩余名额为%d" % course_person) else: time.sleep(1) print("学生-2选择课程失败,没有名额了,请选择其他科目") pass def student3(): print("学生-3开始选择课程...") global course_person if course_person > 0: course_person -= 1 time.sleep(1) print("学生-3选择课程成功,现在剩余名额为%d" % course_person) else: time.sleep(1) print("学生-3选择课程失败,没有名额了,请选择其他科目") pass if __name__ == "__main__": course_person = 2 #课程可容纳选择人数 thread1 = threading.Thread(target=student1,name="thread-1") thread2 = threading.Thread(target=student2, name="thread-2") thread3 = threading.Thread(target=student3, name="thread-3") thread1.start() thread2.start() thread3.start()
运行结果为:
学生-1开始选择课程...
学生-2开始选择课程...
学生-3开始选择课程...
学生-3选择课程失败,没有名额了,请选择其他科目
学生-2选择课程成功,现在剩余名额为0
学生-1选择课程成功,现在剩余名额为0
Process finished with exit code 0
通过上述运行结果可以看出来,上述打印不是我们要的结果,这个是没有加锁的原因,下面我们进行加锁,再看看效果是什么样子的
加锁后的Demo代码:
import threading
import time
def student1():
global lock
with lock:
print("学生-1开始选择课程...")
global course_person
if course_person > 0:
course_person -= 1
time.sleep(1)
print("学生-1选择课程成功,现在剩余名额为%d"%course_person)
else:
time.sleep(1)
print("学生-1选择课程失败,没有名额了,请选择其他科目")
pass
def student2():
global lock
with lock:
print("学生-2开始选择课程...")
global course_person
if course_person > 0:
course_person -= 1
time.sleep(1)
print("学生-2选择课程成功,现在剩余名额为%d" % course_person)
else:
time.sleep(1)
print("学生-2选择课程失败,没有名额了,请选择其他科目")
pass
def student3():
global lock
with lock:
print("学生-3开始选择课程...")
global course_person
if course_person > 0:
course_person -= 1
time.sleep(1)
print("学生-3选择课程成功,现在剩余名额为%d" % course_person)
else:
time.sleep(1)
print("学生-3选择课程失败,没有名额了,请选择其他科目")
pass
if __name__ == "__main__":
course_person = 2 #课程可容纳选择人数
lock = threading.RLock()
thread1 = threading.Thread(target=student1,name="thread-1")
thread2 = threading.Thread(target=student2, name="thread-2")
thread3 = threading.Thread(target=student3, name="thread-3")
thread1.start()
thread2.start()
thread3.start()
运行结果:
可以看出,加锁后的效果就是我们想要的效果。。。