• 多线程的几把锁


    一、信号量

     1 '''100人上厕所的故事'''
     2 import time
     3 import threading
     4 class MyThread(threading.Thread):
     5     def run(self):
     6         if semaphore.acquire():    #上锁
     7             print(self.name)
     8             time.sleep(3)
     9             semaphore.release()    #开锁
    10 
    11 if  __name__ == '__main__':
    12     semaphore = threading.BoundedSemaphore(5)    #创建信号量锁
    13     thrs = []
    14     for i in range(32):
    15         thrs.append(MyThread())    #创建线程
    16     for t in thrs:
    17         t.start()       #开启线程
    18 
    19 '''注释:1.虽然存在GIL锁,Cpython翻译器同时只能执行一个线程。
    20            但当正在执行的线程阻塞时,另一条线程马上被执行,多线程并发效果就被体现出来。
    21          2.信号量也是一把锁,用来设置同一时间可以并发的线程数。
    22            例如:当设置信号量为5时,意味着同一时间只有5条线程可以参与并发执行。
    23                  就好比100个人去上厕所,但只有5个坑;同一时间只有5个人在放肆,当有空缺时,后面的人补上。
    24          3.上述过程不排队,谁先抢到坑位就先执行谁'''

    二、条件变量

     1 '''吃包子的故事'''
     2 import time
     3 import threading
     4 from random import randint
     5 class producer(threading.Thread):
     6     def run(self):
     7         global L
     8         while True:
     9             val = randint(0,100)   #生成0-100的随机数
    10             print('生产者',self.name,'做出了%s号包子' %str(val))
    11             if lock_con.acquire():  #上锁
    12                 L.append(val)     #把做出来的包子加入L列表
    13                 print('笼屉里有以下包子:',L)
    14                 lock_con.notify()   #当L中有包子时,通知waiting的线程启动
    15                 lock_con.release()  #开锁
    16             time.sleep(3)     #生产者每3秒做一个包子
    17 class consumer(threading.Thread):
    18     def run(self):
    19         global L
    20         while True:
    21             lock_con.acquire()    #上锁
    22             if len(L) == 0:
    23                 lock_con.wait()   #L中没包子,条件不满足,自动开锁阻塞并等待通知......。等到通知以后,返回去从上锁开始执行
    24             print('消费者',self.name,'吃掉了%s号包子' %str(L[0]))
    25             del L[0]
    26             print('笼屉里还有的包子为:',L)
    27             lock_con.release()
    28             time.sleep(1)   #消费者每1s吃掉一个包子
    29 
    30 if __name__ == '__main__':
    31     L = []
    32     lock_con = threading.Condition()     #创建条件变量锁
    33     threads = []
    34     for i in range(3):
    35         threads.append(producer())    #创建了3个生产者线程
    36     threads.append(consumer())        #创建了1个消费者线程
    37     for t in threads:
    38         t.start()                     #启动所有线程,一共4个
    39     for t in threads:
    40         t.join()

    三、同步条件event

     1 '''加班的故事'''
     2 import threading,time
     3 class Boss(threading.Thread):
     4     def run(self):
     5         print('Boss:今晚加班到10点')
     6         event.set()   #设置event状态值为True,等待池的线程就绪
     7         time.sleep(5)
     8         print('Boss:到10点了')
     9         event.set()
    10 class worker(threading.Thread):
    11     def run(self):
    12         event.wait()    #如果event状态值为False,线程阻塞
    13         print('唉,万恶的剥削没人管啊....')
    14         event.clear()   #设置状态值为False
    15         event.wait()
    16         print('终于可以回家了,OhYeah!')
    17 if __name__ == '__main__':
    18     event = threading.Event()
    19     threads = []
    20     for i in range(5):
    21         threads.append(worker())
    22     threads.append(Boss())
    23     for t in threads:
    24         t.start()
    25     for t in threads:
    26         t.join()
  • 相关阅读:
    再谈数据湖3.0:降本增效背后的创新原动力
    基于开源PolarDBX打造中正智能身份认证业务数据基座
    开源数据库PolarDB为什么能捕获娃哈哈的心?
    PolarDB开源未来将有哪些新动向?阿里云数据库开源负责人来解答
    谈谈PolarDBX在读写分离场景的实践
    科普达人丨一图看懂块存储&云盘
    科普达人丨一图看懂阿里云ECS
    网络编程框架Netty
    结构型模式
    网络编程框架Netty1
  • 原文地址:https://www.cnblogs.com/Finance-IT-gao/p/10632001.html
Copyright © 2020-2023  润新知