• 多任务-线程之资源竞争问题(互斥锁)


    1.在多线程中,不可避免的一个问题,就是全局变量资源存在着被多个线程调用的问题,在调用的过程中就存在着资源竞争

    2.这种资源竞争是如何产生的呢?

    import threading
    import time
    
    g_num = 0
    
    def work1(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work1, g_num is %d---"%g_num)
    
    
    def work2(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work2, g_num is %d---"%g_num)
    
    
    print("---线程创建之前g_num is %d---"%g_num)
    
    t1 = threading.Thread(target=work1, args=(100,))
    t1.start()
    
    t2 = threading.Thread(target=work2, args=(100,))
    t2.start()
    
    while len(threading.enumerate()) != 1:
        time.sleep(1)
    
    print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)

    如同上述代码,当线程执行次数有限时,全局资源不会发生大的变化,但是当高并发时,就会产生资源竞争问题,如以下代码:

    import threading
    import time
    
    g_num = 0
    
    def work1(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work1, g_num is %d---"%g_num)
    
    
    def work2(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work2, g_num is %d---"%g_num)
    
    
    print("---线程创建之前g_num is %d---"%g_num)
    
    t1 = threading.Thread(target=work1, args=(1000000,))
    t1.start()
    
    t2 = threading.Thread(target=work2, args=(1000000,))
    t2.start()
    
    while len(threading.enumerate()) != 1:
        time.sleep(1)
    
    print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)

    3.如何解决资源竞争问题?

    当存在多个线程或者进程同时调用一个全局变量资源,并且会对它进行修改时,可以采用上锁这个方法,来解决资源竞争问题。

    首先,需要了解什么叫做资源竞争?

    资源竞争是指,一个全局变量资源在多个线程或者进程中被同时调用,造成该全局变量资源不断的被修改。

    解决方法:采用全局变量锁,每当线程调用全局变量时,就将该资源上锁,不允许被调用,只有当调用结束后才打开锁,这里引入互斥锁,能够保证全局变量资源的安全。

    互斥锁的两种状态:锁定/非锁定

    解决资源竞争的好处:互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

    4.互斥锁的定义

    当在请求之前,资源没有被上锁,那么请求并不会堵塞;如果在请求之前,是被锁上的, 那么请求就处于一个堵塞状态,只有当前得锁被打开之后,才能在次上锁。

    互斥锁的优缺点:

      优点:确保了某段关键代码只能由一个线程从头到尾完整地执行

      缺点:阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了

         由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁

    # 创建锁
    mutex = threading.Lock()
    
    # 锁定
    mutex.acquire()
    
    # 释放
    mutex.release()
  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/zxh1297/p/9353037.html
Copyright © 2020-2023  润新知