• Python 线程锁


    一、线程锁(互斥锁Mutex)

      1、一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?

    #!/usr/bin/python
    # -*- coding : utf-8 -*-
    # 作者: Presley
    # 时间: 2018-11-20
    # 邮箱:1209989516@qq.com
    # 这是我用来练习python线程锁的测试脚本
    
    import threading
    import time
    
    
    def addNum():
        global num #在每个线程中都获取这个全局变量
        print("--get num:",num)
        time.sleep(1)
        num -= 1 #对此公共变量进行-1操作
    num = 100 #设定一个共享变量
    thread_list = []
    for i in range(100):
        t = threading.Thread(target=addNum)
        t.start()
        thread_list.append(t)
    for t in thread_list: #等待所有线程执行完毕
        t.join()
    print("final num:",num)

     结果:python2中每次结果都会不一样,python3中结果都是0

    ...
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    final num: 0

      2、加锁后

    #!/usr/bin/python
    # -*- coding : utf-8 -*-
    # 作者: Presley
    # 时间: 2018-11-20
    # 邮箱:1209989516@qq.com
    # 这是我用来练习python线程锁的测试脚本
    
    import threading
    import time
    
    
    def addNum():
        global num #在每个线程中都获取这个全局变量
        print("--get num:",num)
        time.sleep(1)
        lock.acquire() #获取一把锁 #加锁后相当于变成串行的了
        num -= 1 #对此公共变量进行-1操作
        lock.release() #必须释放,不施放所有的都等待了
    
    lock = threading.Lock() #定义一个锁实例
    num = 100 #设定一个共享变量
    thread_list = []
    for i in range(100):
        t = threading.Thread(target=addNum)
        t.start()
        thread_list.append(t)
    for t in thread_list: #等待所有线程执行完毕
        t.join()
    print("final num:",num)

    结果:

    ...
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    --get num: 100
    final num: 0

     二、递归锁(RLock)

      1、说白了就是在一把大锁中还要再包含子锁。

        

    #!/usr/bin/python
    # -*- coding : utf-8 -*-
    # 作者: Presley
    # 时间: 2018-11-21
    # 邮箱:1209989516@qq.com
    # 这是我用来练习python线程锁的测试脚本
    
    import threading
    import time
    
    
    def run1():
        print("grab the first part data")
        lock.acquire()
        global num
        num += 1
        lock.release()
        return num
    def run2():
        print("grab the second part data")
        lock.acquire()
        global num2
        num2 += 1
        lock.release()
        return num2
    def run3():
        lock.acquire() #之所以在执行run1和run2之间加一把锁是因为确保两个方法一块运行完毕
        res = run1()
        print("-------between run1 and run2-----------")
        res2 = run2()
        lock.release()
        print(res,res2)
    if __name__ == "__main__":
        num,num2 = 0,0
        lock = threading.RLock()
        for i in range(10):
            t = threading.Thread(target=run3)
            t.start()
    while threading.active_count() != 1:    #现在还有几个线程,如果等于1表示只有主线程了,否则表示还没有执行完
        print(threading.active_count())
    else:
        print("--all threads done--")
        print(num,num2)

    执行结果:

    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    1 1
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    2 2
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    3 3
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    4 4
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    5 5
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    6 6
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    7 7
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    8 8
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    9 9
    grab the first part data
    -------between run1 and run2-----------
    grab the second part data
    10 10
    --all threads done--
    10 10

    三、信号量(Semaphore)

      1、互斥锁,同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据,比如厕所有三个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

    #!/usr/bin/python
    # -*- coding : utf-8 -*-
    # 作者: Presley
    # 时间: 2018-11-21
    # 邮箱:1209989516@qq.com
    # 这是我用来练习python线程锁的测试脚本
    
    import threading
    import time
    
    
    def run(n):
        semaphore.acquire()
        time.sleep(1)
        print("run the thread:%s 
    " %n)
        semaphore.release()
    
    if __name__ == "__main__":
        num = 0
        semaphore = threading.BoundedSemaphore(3) #最多允许5个线程同时运行,类似于线程池的概念
        for i in range(20):
            t = threading.Thread(target=run,args=(i,))
            t.start()

      执行结果:

    run the thread:1 
    
    run the thread:0 
    
    run the thread:2 
    
    run the thread:3 
    
    run the thread:4 
    
    run the thread:5 
    
    run the thread:6 
    
    run the thread:7 
    run the thread:8 
    
    
    run the thread:9 
    
    run the thread:11 
    run the thread:10 
    
    
    run the thread:12 
    
    run the thread:13 
    run the thread:14 
    
    
    run the thread:15 
    
    run the thread:17 
    
    run the thread:16 
    
    run the thread:18 
    
    run the thread:19 
  • 相关阅读:
    js没有重载
    零基础学习hadoop到上手工作线路指导(初级篇)
    hadoop1.x和2.x的一些主要区别
    LIBCURL教程
    钩子函数大全(2)
    Visual Studio快捷键
    Linux上搭建Hadoop2.6.3集群以及WIN7通过Eclipse开发MapReduce的demo
    Hadoop2.7.1安装与配置
    超详细单机版搭建hadoop环境图文解析
    Windows下运行Hadoop
  • 原文地址:https://www.cnblogs.com/Presley-lpc/p/9991291.html
Copyright © 2020-2023  润新知