0
点赞
收藏
分享

微信扫一扫

network专栏 02.进程与线程 02.互斥锁

有态度的萌狮子 2022-03-26 阅读 56
python
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个元组:(优先级[越小越高],数据)
"""
举报

相关推荐

0 条评论