zoukankan      html  css  js  c++  java
  • 多线程锁,线程池,消费者生产者模型

    锁是怎么存在的?

    在python建立之初,开发者目的是为了快速把语言开发出来,如果加上GIL(c语言加锁),切换时按照100条字节指令来进行线程间的切换

    为什么加锁?

    非线程安全,控制一段代码

    1.lock = threading.BoundedSemaphore
    一次可以限制关卡,限制通行次数,不过这个是写死的
     1 import time
     2 import threading
     3 lock = threading.BoundedSemaphore(3)#一次放三个(一次只通行三个)
     4 def func(arg):
     5     lock.acquire()
     6     time.sleep(1)
     7     print(arg)
     8     lock.release()
     9 for i in range(20):
    10     t = threading.Thread(target=func, args=(i,))
    11     t.start()

    2.

    lock = threading.Condition()
    一次可以限制关卡,限制通行次数,不过这个是写活的
    可以自定义加载个数 ,只需在后面便利后加一个参数
    lock.notify(inp) inp 来限制次数
     1 lock = threading.Condition()
     2 def func(arg):
     3     print('线程进来了')
     4     lock.acquire()
     5     lock.wait() # 加锁这个特殊需要等待参数传递
     6     print(arg)
     7     time.sleep(1)
     8     lock.release()
     9 for i in range(10):
    10     t =threading.Thread(target=func,args=(i,))
    11     t.start()
    12 while True:
    13     inp = int(input('>>>'))
    14     lock.acquire()
    15     lock.notify(inp)#加的控制次数的 这个是特殊的
    16     lock.release()

    3.

    lock = threading.Event()  获取全部
    注意.获取全部使用
    lock.wait() 加锁的
    input(">>>>") 是用来控制是否全部获取的一个开关,一旦输入 ,解锁会获取全部  后面需要加入 lock.set() 绿灯
    如果想再次使用这个函数,
    lock.clear() 重新清空
     1 import time
     2 import threading
     3 
     4 lock = threading.Event()
     5 
     6 def func(arg):
     7     print('线程来了')
     8     lock.wait() # 加锁:红灯
     9     print(arg)
    10 for i in range(10):
    11     t =threading.Thread(target=func,args=(i,))
    12     t.start()
    13 input(">>>>")
    14 lock.set() # 绿灯
    15 lock.clear() # 再次变红灯
    16 for i in range(10):
    17     t =threading.Thread(target=func,args=(i,))
    18     t.start()
    19 input(">>>>")
    20 lock.set()

    4.

     v = threading.local()#内部创建一个属于自己的值 phone=arg 为了区分自己拿的包
     1 import time
     2 import threading
     3 v = threading.local()
     4 def func(arg):
     5     # 内部会为当前线程创建一个空间用于存储:phone=自己的值
     6     v.phone = arg
     7     time.sleep(2)
     8     print(v.phone,arg) # 去当前线程自己空间取值
     9 for i in range(10):
    10     t =threading.Thread(target=func,args=(i,))
    11     t.start()

    线程池: 用来约束每次输出的次数,不是全部哪出啊,可以限制一次拿出几个

    1 from concurrent.futures import ThreadPoolExecutor
    2 import  time
    3 def func(a1,a2):
    4     time.sleep(5)
    5     print(a1,a2)
    6 a=ThreadPoolExecutor(4)#实例化对象让其限制次数 
    7 for i  in  range(40):
    8     a.submit(func,i,15)

    生产者,消费者模型

    这种模型在多线程中属于按顺序使用  现有生产才有消费,这个是一个固定顺序,而在函数中,为了更明确这种概念而不考虑生产时间限制

    来更符合逻辑性 出现了queue 模块  首先实例化对象  q=queue.Queue 在用方法q.put(" ") 括号里面必须有字符串提示从这里入,符合队列(先进先出)而抛开逻辑

    后面用q.get( ) 方法提示出来了

     1 import time
     2 import threading
     3 import queue
     4 q=queue.Queue()#实例化对象
     5 def mk(id):
     6     while 1:
     7         time.sleep(3)
     8         q.put("布加迪")#首先进入q.put
     9         print("师傅%s 生产了一个布加迪"% id)
    10 for i  in  range(1,3):
    11     t=threading.Thread(target=mk,args=(i,))
    12     t.start()
    13 def et(id):
    14     while 1:
    15         time.sleep(1)
    16         v1=q.get()#然后冲进去
    17         print("连达%s 吃了一个布加迪"% id)
    18 for i  in  range(1,6):
    19     t1=threading.Thread(target=et,args=(i,))
    20     t1.start()
  • 相关阅读:
    python之面向对象之类变量和实例变量
    python之面向对象之封装
    python之shutil模块
    利用python实现冒泡排序
    利用python实现二分法和斐波那契序列
    thinkphp input
    从右向左
    全局修改composer源地址
    Git忽略规则及.gitignore规则不生效的解决办法
    mysql主从数据库不同步的2种解决方法 (转载)
  • 原文地址:https://www.cnblogs.com/zhangqing979797/p/9628884.html
Copyright © 2011-2022 走看看