zoukankan      html  css  js  c++  java
  • 浅谈线程锁和进程锁

    ​ 在python的多线程和多进程中,当我们需要对多线程或多进程的共享资源或对象进行修改操作时,往往会出现因cpu随机调度而导致结果和我们预期不一致的问题,

    线程举例:

    from threading import Thread,Lock
    
    x = 0
    def task():
        global x
        for i in range(200000):
            x = x+1
    '''
    假设
    t1 的 x刚拿到0 保存状态 就被切了
    t2 的 x拿到0 进行+1       1
    t1 又获得运行了  x = 0  +1  1
    思考:一共加了几次1? 加了两次1 真实运算出来的数字本来应该+2 实际只+1
    这就产生了数据安全问题.
    '''        
    
    
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t3 = Thread(target=task)
        t1.start()
        t2.start()
        t3.start()
        t1.join()
        t2.join()
        t3.join()
        print(x)
    

    479261

    from  multiprocessing import Process,Lock
    import json,time,os
    
    def search():
        time.sleep(1) # 模拟网络io
        with open('db.txt',mode='rt',encoding='utf-8') as f:
            res = json.load(f)
            print(f'还剩{res["count"]}')
    
    def get():
        with open('db.txt',mode='rt',encoding='utf-8') as f:
            res = json.load(f)
        time.sleep(1) # 模拟网络io
        if res['count'] > 0:
            res['count'] -= 1
            with open('db.txt',mode='wt',encoding='utf-8') as f:
                json.dump(res,f)
                print(f'进程{os.getpid()} 抢票成功')
            time.sleep(1.5) # 模拟网络io
        else:
            print('票已经售空啦!!!!!!!!!!!')
    
    def task():
        search()
        get()
    
    if __name__ == '__main__':
    
        for i in range(5):
            p = Process(target=task)
            p.start()
    
    

    还剩1
    还剩1
    还剩1
    还剩1
    还剩1
    进程6292 抢票成功
    进程10604 抢票成功
    进程19280 抢票成功
    进程272 抢票成功
    进程12272 抢票成功

    这时就需要对线程或者进程加锁,以保证一个线程或进程在对共享对象进行修改时,其他的线程或进程无法访问这个对象,直至获取锁的线程的操作执行完毕后释放锁。所以,锁在多线程和多进程中起到一个同步的作用,以保护每个线程和进程必要操作的完整执行。

    #线程锁
    from threading import Thread,Lock
    
    x = 0
    mutex = Lock()
    def task():
        global x
        mutex.acquire()
        for i in range(200000):
            x = x+1
    
        mutex.release()
    
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t3 = Thread(target=task)
        t1.start()
        t2.start()
        t3.start()
        t1.join()
        t2.join()
        t3.join()
        print(x)
    

    600000

    from  multiprocessing import Process,Lock
    import json,time,os
    
    def search():
        time.sleep(1) # 模拟网络io
        with open('db.txt',mode='rt',encoding='utf-8') as f:
            res = json.load(f)
            print(f'还剩{res["count"]}')
    
    def get():
        with open('db.txt',mode='rt',encoding='utf-8') as f:
            res = json.load(f)
            # print(f'还剩{res["count"]}')
        time.sleep(1) # 模拟网络io
        if res['count'] > 0:
            res['count'] -= 1
            with open('db.txt',mode='wt',encoding='utf-8') as f:
                json.dump(res,f)
                print(f'进程{os.getpid()} 抢票成功')
            time.sleep(1.5) # 模拟网络io
        else:
            print('票已经售空啦!!!!!!!!!!!')
    
    def task(lock):
        search()
    
        # 锁住
        lock.acquire()
        get()
        lock.release()
        # 释放锁头
    
    if __name__ == '__main__':
        lock = Lock() # 写在主进程是为了让子进程拿到同一把锁.
        for i in range(15):
            p = Process(target=task,args=(lock,))
            p.start()
            # p.join()
    
        #  进程锁 是把锁住的代码变成了串行
        #  join 是把所有的子进程变成了串行
    
    
    # 为了保证数据的安全,串行牺牲掉效率.
    

    还剩1
    还剩1
    还剩1
    还剩1
    还剩1
    进程16868 抢票成功
    票已经售空啦!!!!!!!!!!!
    票已经售空啦!!!!!!!!!!!
    票已经售空啦!!!!!!!!!!!
    票已经售空啦!!!!!!!!!!!

  • 相关阅读:
    翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
    翻译「C++ Rvalue References Explained」C++右值引用详解 Part4:强制Move语义
    翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用
    翻译「C++ Rvalue References Explained」C++右值引用详解 Part2:Move语义
    python第一部分基础题1-80题
    django rest_framework 框架的使用03
    django rest_framework 框架的使用02
    django rest_framework 框架的使用
    Django ORM-02
    Django ORM-01
  • 原文地址:https://www.cnblogs.com/MrYang161/p/11543145.html
Copyright © 2011-2022 走看看