• [b0031] python 归纳 (十六)_线程同步_锁


    # -*- coding: utf-8 -*-
    """
    学习 多线程同步  使用锁 threading.Lock()
    逻辑:
      2 个线程,操作同一个整型变量,一个加法,另外一个减法
    
    总结:
       1. 锁不是加在共享数据上,不像数据库锁加在数据上 ,好像是锁定修改数据的程序代码,任何时候,锁定的代码
           最多被一个线程执行
       2. 某段操作共享数据的代码加锁了,如果共享数据在代码其他地方有修改逻辑,没加锁
           数据逻辑性无法保证
       3. 锁获得,释放之间的代码可以不操作共享数据 ,仅仅实现线程之间的控制协调关系
       4. 代码中可以使用多个锁,但是可能 造成死锁,相互等待对方的锁
    
       有几个并发程序, 要不要操作共享数据,在代码哪里加锁,哪里释放锁。都要考虑进去
       后 ,才能保证程序逻辑正确
       操作共享数据, 应该 在所有修改数据的地方,加上同一把锁
       读取数据的地方,根据逻辑,判断是否加上锁
    
    
    使用:
       1. 创建锁 lock = threading.Lock()
       2. 在某段代码开始 获取锁 lock.acquire()
       3. 在某段代码结束 释放锁 lock.release()
    
    相关:
     threading.RLock()
    
    """
    
    import threading
    import time
    
    lock = threading.Lock() #
    data = 0  # 共享数据
    
    class Thread1(threading.Thread):
        def __init__(self,item):
            threading.Thread.__init__(self)
            self.item = item
        def run(self):
            print("begin",threading.currentThread().getName(),time.strftime('%M:%S',time.localtime(time.time())))
            global data
            lock.acquire()   # 获取锁
            time.sleep(2)
            data += 1
            print(threading.currentThread().getName(),data)
            time.sleep(2)
            data += 1
            lock.release()   # 释放锁
            print(threading.currentThread().getName(),data)
            print "
    ","end",threading.currentThread().getName(),time.strftime('%M:%S',time.localtime(time.time()))
    
    class Thread2(threading.Thread):
        def __init__(self,item):
            threading.Thread.__init__(self)
            self.item = item
        def run(self):
            print("begin",threading.currentThread().getName(),time.strftime('%M:%S',time.localtime(time.time())))
            time.sleep(1)
            global data
            lock.acquire()  # 获取锁
            time.sleep(2)
            data -= 2
            print(threading.currentThread().getName(),data)
            time.sleep(2)
            data -= 2
            lock.release()   # 释放锁
            print(threading.currentThread().getName(),data)
            print "
    ","end",threading.currentThread().getName(),time.strftime('%M:%S',time.localtime(time.time()))
    
    
    t1 = Thread1(0)
    t2 = Thread2(0)
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()
    
    print "end"
    
    """
    Out:
    
    ('begin', 'Thread-1', '35:47')
    ('begin', 'Thread-2', '35:47')
    ('Thread-1', 1)
    ('Thread-1', 2)
    
    end Thread-1 35:51
    ('Thread-2', 0)
    ('Thread-2', -2)
    
    end Thread-2 35:55
    end
    """
    
    
    """
    Thread2的锁操作注释掉
    Out:
    
    ('begin', 'Thread-1', '36:29')
    ('begin', 'Thread-2', '36:29')
    ('Thread-1', 1)
    ('Thread-2', -1)
    ('Thread-1', 0)
    
    end Thread-1 36:33
    ('Thread-2', -2)
    
    end Thread-2 36:34
    end
    """

    Out1 保证 在操作共享数据的地方,执行完线程1,再执行线程2

    Out2 即使在线程1中加了锁,但是线程2没有加锁,两个代码在同时跑。 数据一致性无法保证

  • 相关阅读:
    Java 练习(获取两个字符串中最大相同子串)
    STM32F103 实现 简易闹钟小程序
    STM32F103 实现 LCD显示年月日时分秒星期 并可逐值修改的日期 小程序
    Docker报错之“Failed to get D-Bus connection: Operation not permitted”
    数据结构解析
    每天一条DB2命令-004
    每天一条DB2命令-003
    每天一条DB2命令-002
    ElasticSearch系列
    模块三 GO语言实战与应用-BYTES包与字节串操作(下)
  • 原文地址:https://www.cnblogs.com/sunzebo/p/9624948.html
Copyright © 2020-2023  润新知