from threading import Thread, Lock
import time
"""
因为线程是公用同一个全局变量,因此锁可以放在全局变量位置
由于每个进程会创建自己的资源,因此进程锁要放在创建进程之前的位置
"""
mutex = Lock()
money = 100
def task():
global money
# 上锁
mutex.acquire()
temp = money
time.sleep(0.01)
money = temp - 1
# 解锁
mutex.release()
"""
自动加锁,自动解锁
with mutex:
temp = money
time.sleep(0.01)
money = temp - 1
"""
if __name__ == '__main__':
# 开启100个线程
t_list = []
for i in range(100):
t = Thread(target=task)
t.start()
# 将线程添加到线程列表中
t_list.append(t)
print(money)
for t in t_list:
# 子线程结束后,主线程才会继续运行
t.join()
print(money)
print(money)
"""
python解释器有多个版本
C_python[普遍使用]、J_python、PyPython等
在C_python解释器中,GIL是一把互斥锁,用来阻止同一进程下的多线程同时执行
阻止原因:防止定义一半的内容被垃圾回收线程错误回收
非IO操作时,抢到GIL锁的线程在执行完毕后,才会释放GIL锁
"""
"""
死锁的原因:
Thread-1 抢到A锁
Thread-1 抢到B锁
Thread-1 抢到B锁
Thread-2 抢到A锁
递归锁:
可以被连续的acquire和release的锁
只能被第一个抢到这把锁的对象执行
每acquire一次,计数+1,每release一次,计数-1
只要计数不为0,其他人都无法抢到锁
"""
from threading import Thread, Lock, RLock
mutexA = Lock()
mutexB = Lock()
# # mutexA与mutexB是不同的对象
# 递归锁
# mutexA = mutexB = RLock()
class MyThread(Thread):
def run(self):
self.func_01()
self.func_02()
def func_01(self):
mutexA.acquire()
print(f'{self.name} 抢到A锁')
mutexB.acquire()
print(f'{self.name} 抢到B锁')
mutexB.release()
mutexA.release()
def func_02(self):
mutexB.acquire()
print(f'{self.name} 抢到B锁')
mutexA.acquire()
print(f'{self.name} 抢到A锁')
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(2):
t = MyThread()
t.start()
"""
同时开启多个互斥锁
"""
from threading import Thread, Semaphore
import time
import random
# 设置互斥锁的数量
sm = Semaphore(3)
def task(name):
sm.acquire()
print(f'{name} is running')
time.sleep(random.randint(3, 6))
sm.release()
if __name__ == '__main__':
for i in range(6):
# 同一时间可同时执行3个进程
t = Thread(target=task, args=(f'{i}',))
t.start()
from threading import Thread, Event
import time
# 创建一个事件对象
event = Event()
def light():
print('red is running')
time.sleep(3)
print('green is running')
# 告诉等待红灯的人可以走了
event.set()
def car(name):
print(f'Number{name} is waiting')
# 等待别人给你发消息
event.wait()
print(f'{name} go')
if __name__ == '__main__':
# 开启红绿灯线程
t = Thread(target=light)
t.start()
for i in range(12):
t = Thread(target=car, args=(f'{i}', ))
t.start()
"""
队列是用于连接进程与进程间的数据
同一个进程下的多个线程,数据是共享的
队列是管道+锁组成的,为了保证数据安全,同一进程下的多线程也会使用队列
队列queue
先进先出:Queue
先进后出:LifoQueue
按优先级:PriorityQueue 传入数据时,传入1个元组:(优先级[越小越高],数据)
"""