• 线程锁 死锁现象 递归锁 信号量 条件定时器 队列 线程池


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

    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()
    定时器



  • 相关阅读:
    .netcore初体验
    ASP.NET MVC实现单用户登录
    远程连接桌面报:这可能是由于credssp加密oracle修正
    想起以前写的一个爬虫,然后就用C#WinForm写了一个下载小说的软件,比较简单
    List泛型与DataTable相互转换
    SqlServer-触发器
    SqlServer-RBAC五表权限
    SqlServer通用存储过程
    用vs2017结果无法启动IIS express
    简单的叙述下SQL中行列转换的小知识!
  • 原文地址:https://www.cnblogs.com/liurenli/p/10111174.html
Copyright © 2020-2023  润新知