zoukankan      html  css  js  c++  java
  • 线程锁 死锁现象 递归锁 信号量 条件定时器 队列 线程池

    锁是用来做什么的?
        保证数据的安全的

    GIL是干什么的?
          锁线程

    有了GIL还要锁干啥?

          有了GIL还是会出现数据不安全的现象,所以还是要用锁
    import time
    from threading import Thread,Lock
    n = 100
    def func(lock):
        global n
        # n -= 1
        with lock:
            tmp = n-1  # n-=1
            time.sleep(0.1)
            n = tmp
    
    if __name__ == '__main__':
        l = []
        lock = Lock()
        for i in range(100):
            t = Thread(target=func,args=(lock,))
            t.start()
            l.append(t)
        for t in l:t.join()
        print(n)

    dis模块的使用

    import dis
    n = 1
    def func():
    n = 100
    n -= 1

    dis.dis(func)

    会出现线程不安全的两个条件
    1.是全局变量
    2.出现 += -=这样的操作


    列表 字典
    方法 l.append l.pop l.insert dic.update 都是线程安全的
    l[0] += 1
    d[k] += 1


    死锁现象
    # 科学家吃面问题
    import time
    from threading import Thread,Lock
    # noodle_lock = Lock()
    # fork_lock = Lock()
    # 死锁不是时刻发生的,有偶然的情况整个程序都崩了
    # 每一个线程之中不止一把锁,并且套着使用
    # 如果某一件事情需要两个资源同时出现,那么不应该将这两个资源通过两把锁控制
    # 而应看做一个资源
    def eat1(name):
        noodle_lock.acquire()
        print('%s拿到面条了'%name)
        fork_lock.acquire()
        print('%s拿到叉子了'%name)
        print('%s开始吃面'%name)
        time.sleep(0.2)
        fork_lock.release()
        print('%s放下叉子了' % name)
        noodle_lock.release()
        print('%s放下面了' % name)
    
    def eat2(name):
        fork_lock.acquire()
        print('%s拿到叉子了' % name)
        noodle_lock.acquire()
        print('%s拿到面条了' % name)
        print('%s开始吃面' % name)
        time.sleep(0.2)
        noodle_lock.release()
        print('%s放下面了' % name)
        fork_lock.release()
        print('%s放下叉子了' % name)
    
    Thread(target=eat1,args=('alex',)).start()
    Thread(target=eat2,args=('wusir',)).start()
    Thread(target=eat1,args=('太白',)).start()
    Thread(target=eat2,args=('宝元',)).start()
    lock = Lock()
    def eat1(name):
        lock.acquire()
        print('%s拿到面条了'%name)
        print('%s拿到叉子了'%name)
        print('%s开始吃面'%name)
        time.sleep(0.2)
        lock.release()
        print('%s放下叉子了' % name)
        print('%s放下面了' % name)
    
    def eat2(name):
        lock.acquire()
        print('%s拿到叉子了' % name)
        print('%s拿到面条了' % name)
        print('%s开始吃面' % name)
        time.sleep(0.2)
        lock.release()
        print('%s放下面了' % name)
        print('%s放下叉子了' % name)
    
    Thread(target=eat1,args=('alex',)).start()
    Thread(target=eat2,args=('wusir',)).start()
    Thread(target=eat1,args=('太白',)).start()
    Thread(target=eat2,args=('宝元',)).start()
     互斥锁
    # 无论在相同的线程还是不同的线程,都只能连续acquire一次
    # 要想再acquire,必须先release
    # 递归锁
    # 在同一个线程中,可以无限次的acquire
    # 但是要想在其他线程中也acquire,
    # 必须现在自己的线程中添加和acquire次数相同的release

    # rlock = RLock()
    # rlock.acquire()
    # rlock.acquire()
    # rlock.acquire()
    # rlock.acquire()
    # print('锁不住')
    
    # lock = Lock()
    # lock.acquire()
    # print('1')
    # lock.acquire()
    # print('2')
    
    # rlock = RLock()
    # def func(num):
    #     rlock.acquire()
    #     print('aaaa',num)
    #     rlock.acquire()
    #     print('bbbb',num)
    #     rlock.release()
    #     rlock.release()
    #
    # Thread(target=func,args=(1,)).start()
    # Thread(target=func,args=(2,)).start()
    import time
    noodle_lock = fork_lock = RLock()
    def eat1(name):
        noodle_lock.acquire()
        print('%s拿到面条了'%name)
        fork_lock.acquire()
        print('%s拿到叉子了'%name)
        print('%s开始吃面'%name)
        time.sleep(0.2)
        fork_lock.release()
        print('%s放下叉子了' % name)
        noodle_lock.release()
        print('%s放下面了' % name)
    
    def eat2(name):
        fork_lock.acquire()
        print('%s拿到叉子了' % name)
        noodle_lock.acquire()
        print('%s拿到面条了' % name)
        print('%s开始吃面' % name)
        time.sleep(0.2)
        noodle_lock.release()
        print('%s放下面了' % name)
        fork_lock.release()
        print('%s放下叉子了' % name)
    
    Thread(target=eat1,args=('alex',)).start()
    Thread(target=eat2,args=('wusir',)).start()
    Thread(target=eat1,args=('太白',)).start()
    Thread(target=eat2,args=('宝元',)).start()
    信号量和池
    # 进程池
    # 有1000个任务
    # 一个进程池中有5个进程
    # 所有的1000个任务会多次利用这五个进程来完成任务
    # 信号量
    # 有1000个任务
    # 有1000个进程/线程
    # 所有的1000个任务由于信号量的控制,只能5个5个的执行

    import time
    from threading import Semaphore,Thread
    
    def func(name,sem):
        sem.acquire()
        print(name,'start')
        time.sleep(1)
        print(name,'stop')
        sem.release()
    
    sem = Semaphore(5)
    for i in range(20):
        Thread(target=func,args=(i,sem)).start()
    定时器



  • 相关阅读:
    m_Orchestrate learning system---三、session使用完整流程是什么
    m_Orchestrate learning system---四、多看参考文档很多事情很轻松就解决了
    m_Orchestrate learning system---五、学的越多,做的越快
    m_Orchestrate learning system---六、善用组件插件的好处是什么
    m_Orchestrate learning system---七、如何快速学好前端
    cocos2d0基础知识三个音符
    URAL 1727. Znaika's Magic Numbers(数学 vector)
    第13周项目2-纯虚函数形类家庭
    [cocos2dx注意事项009]试用quick-cocos2dx-2.2.4
    百度之星 1004 Labyrinth
  • 原文地址:https://www.cnblogs.com/liurenli/p/10111174.html
Copyright © 2011-2022 走看看