zoukankan      html  css  js  c++  java
  • 锁,threading local,以及生产者和消费者模型

    1.锁:Lock(一次放行一个)

      线程安全,多线程操作时,内部会让所有的线程排队处理。

      线程不安全:+人=>排队处理

      以后锁代码块

    v=[]
    lock=threading.Lock()#声明锁
    def func(arg):
        lock.acquire()#上锁
        v.append(arg)
        time.sleep(0.1)
        m=v[-1]
        print(arg,m)
        lock.release()#解锁
    for i in range(10):
        t=threading.Thread(target=func,args=(i,))
        t.start()
    0 0
    1 1
    2 2
    3 3
    4 4
    5 5
    6 6
    7 7
    8 8
    9 9

    2.锁:Rlock(一次放一个)

      支持递归锁,锁多次

    v = []
    lock = threading.RLock()
    def func(arg):
        lock.acquire()
        # lock.acquire()
    
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
    
        lock.release()
        # lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    0 0
    1 1
    2 2
    3 3
    4 4
    5 5
    6 6
    7 7
    8 8
    9 9

    3.一次放多个:BoundedSemaphore

      threading.BoundedSemaphore(指定一次放几个就放几个),信号量

    import time
    import threading
    lock=threading.BoundedSemaphore(5)#指定几个就每次执行几个线程
    def func(arg):
        lock.acquire()
        print(arg)
        time.sleep(3)
        lock.release()
    for i in range(20):
        t=threading.Thread(target=func,args=(i,))
        t.start()

    4.条件锁Condition(一次放指定个数,用户输入几个就放几个)******

    方法一:
    import
    time import threading lock=threading.Condition()#声明放的方式 def func(arg): lock.acquire() lock.wait()#上锁 print(arg) time.sleep(2) lock.release() for i in range(20): t=threading.Thread(target=func,args=(i,)) t.start() while 1: user=int(input(">>>")) lock.acquire() lock.notify(user)#重点操作 lock.release()
    方法二:
    def xxx():
    input('>>>')
    return True
    def func(arg):
    lock.wait_for(xxx)
    print(arg)
    time.sleep(1)
    for i in range(10):
    t=threading.Thread(target=func,args=(i,))
    t.start()

    5.Event(一次放所有)

    import threading
    import time
    lock=threading.Event()声明一次放掉全部的线程
    def func(arg):
    lock.wait()加锁红灯
    print(arg)
    for i in range(10):
    t=threading.Thread(target=func,args=(i,))
    t.start()
    input('>>>')
    lock.set()解锁绿灯
    lock.clear()再次红灯
    for i in range(10):
    t=threading.Thread(target=func,args=(i,))
    t.start()
    input('>>>')
    lock.set()绿灯

     

    总结:

      线程安全:列表和字典是线程安全的,队列。

      为什么要加锁?

      非线程安全的可以人为加锁,控制一段代码!

    6.threading.local

    作用:

      内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值,保证线程之间的数据隔离。

    应用:
    import
    threading import time v=threading.local() def func(arg): v.phone=arg time.sleep(2) print(v.phone,arg) for i in range(10): t=threading.Thread(target=func,args=(i,)) t.start()
    原理:
    import threading
    import time
    v=threading.local()
    def func(arg):
    v.phone=arg
    time.sleep(2)
    print(v.phone,arg)
    for i in range(10):
    t=threading.Thread(target=func,args=(i,))
    t.start()

    7.线程池:控制最多开指定的线程

    import threading
    from concurrent.futures import ThreadPoolExecutor
    import time
    def func(a1,a2):
        time.sleep(2)
        print(a1,a2)
    pool = ThreadPoolExecutor(5)#创建线程池,最多5个线程
    for i in range(20):
        #去线程池中申请一个线程,让线程执行该函数
        pool.submit(func,i,20)

    8.生产者消费者模型

    import threading
    import queue
    import time
    q=queue.Queue()#线程安全
    def func(id):
        """
        生产者
        :param id:
        :return:
        """
        while 1:
            time.sleep(2)
            q.put('包子')
            print('厨子%s,做了一个包子' %id)
    for i in range(1,5):
        t=threading.Thread(target=func,args=(i,))
        t.start()
    def usera(id):
        """
        消费者
        :param id: 
        :return: 
        """
        while 1:
            q.get()
            print('第%s个顾客吃了一个包子' %id)
    for i in range(1,8):
        t=threading.Thread(target=usera,args=(i,))
        t.start()

    队列:先进先出

    扩展:

      栈:后进先出

    内容补充:

    线程池在python2中是没有的,线程不能太多,会造成线程的上下切换,影响效率

    进程和线程的区别?

    1.进程是CPU资源分配的最小单元

    线程是CPU计算的最小单元

    2.一个进程中可以有多个线程,

    3.对于python来说,进程线程和其他语言有差异,是由gill锁造成的,gill锁保证一个进程中,同一时刻只能有一个线程能被CPU调度

    进程是进行数据隔离

    线程是CPU工作的最小单元,共享进程中的所有资源,每个线程分担一些任务,最终执行

  • 相关阅读:
    Oracle的hash分区
    Oracle的list分区
    range联合分区
    Oracle分区表range单分区
    彻底解决Oracle unable to create INITIAL extent for segment in tablespace xx
    Oracle表空间管理,数据迁移,
    plsqldevelop安装教程
    count(*)与count列谁快谁慢
    阿里云服务器Centos6.9安装oracle11g单实例数据库
    字符转换二进制码
  • 原文地址:https://www.cnblogs.com/wqzn/p/9628535.html
Copyright © 2011-2022 走看看