zoukankan      html  css  js  c++  java
  • python锁

    锁的概念是因为多线程而提出的,必须在线程中才能体现出锁的作用。

    没用锁的情况:

    import threading
    import time
    
    gl_num = 0
    
    def show(arg):
        global gl_num
        n = gl_num
        time.sleep(1)
        gl_num = n+1
        print(gl_num)
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    没用锁的代码
    main thread stop
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    运行结果

    可以看到,在没用锁的情况下,线程同时取到0并加1,结果都为1.

    什么是锁?

      锁,跟门锁一样,他的作用不是为了锁定这个门,而是为了锁定门后的一方世界,也就是代码块。

      

    import threading
    import time
    
    lock = threading.RLock()
    gl_num = 0
    def show(arg):
        lock.acquire()
        global gl_num
        n = gl_num
        time.sleep(1)
        gl_num = n+1
        lock.release()
        print(gl_num)
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    加上锁
    main thread stop
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    结果

    锁都有那些呢?

      两种:Lock(指令锁、RLock(可重入锁)。Lock属于全局,Rlock属于线程。

    学习lock和Rlock区别前,我们要搞清楚什么事死锁。

    死锁是:比如一辆车被两把锁锁住,你单单拿到一把锁的钥匙,你是开不了这个车的,这就是死锁。当然,这里是抽象的锁概念跟现实还有很大区别。

    import threading
    import time
    
    lock = threading.Lock()
    gl_num = 0
    def show(arg):
        lock.acquire()
        print('我只执行一次就被锁住了。',threading.current_thread().name)
        lock.acquire()
        time.sleep(1)
        print(threading.current_thread().name)
        lock.release()
        lock.release()
    
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    死锁
    我只执行一次就被锁住了。 Thread-1
    main thread stop
    结果

    那么这死锁怎么解决?呵呵,用Rlock,这因为就是他们的区别了。

    import threading
    import time
    
    lock = threading.RLock()
    gl_num = 0
    def show(arg):
        lock.acquire()
        print('我只执行一次就被锁住了。',threading.current_thread().name)
        lock.acquire()
        time.sleep(1)
        print(threading.current_thread().name)
        lock.release()
        lock.release()
    
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    Rlock解决死锁,代码几乎不变
    我只执行一次就被锁住了。 Thread-1
    main thread stop
    Thread-1
    我只执行一次就被锁住了。 Thread-2
    Thread-2
    我只执行一次就被锁住了。 Thread-3
    Thread-3
    我只执行一次就被锁住了。 Thread-4
    Thread-4
    我只执行一次就被锁住了。 Thread-5
    Thread-5
    我只执行一次就被锁住了。 Thread-6
    Thread-6
    我只执行一次就被锁住了。 Thread-7
    Thread-7
    我只执行一次就被锁住了。 Thread-8
    Thread-8
    我只执行一次就被锁住了。 Thread-9
    Thread-9
    我只执行一次就被锁住了。 Thread-10
    Thread-10
    结果

     总结

    1、线程如果共用同一个数据(栈、队列),如果相互之间存在数据污染,那么就需要锁的来将操作公共数据的代码块锁起来。

    2、锁的获取:lock = threading.Lock()或者lock = threading.RLock(),

    3、lock跟RLock的区别,使用多把锁,那就需要Rlock来解决死锁问题。这里说的多把锁,是指一个锁多个嵌套。

  • 相关阅读:
    idea spring boot 1.x junit单元测试
    linux oracle/jdk启用大页面
    jdk8之CompletableFuture与CompletionService
    gc日志深入解析-覆盖CMS、并行GC、G1、ZGC、openj9
    h2 web console使用
    LockSupport工具类详解
    反射、Unsafe、直接调用性能大比拼
    spring boot druid动态多数据源监控集成
    Linux网络
    org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection总结
  • 原文地址:https://www.cnblogs.com/hardykay/p/10203275.html
Copyright © 2011-2022 走看看