zoukankan      html  css  js  c++  java
  • 多任务-线程之资源竞争问题(互斥锁)

    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()
  • 相关阅读:
    grid 布局
    数组对象
    定义换页时表现
    判断一个对象是否为空
    内存管理 内存泄漏
    arguments对象
    String类型
    对象 实例
    iOS 之 UIWebView
    iOS 之 内嵌网页
  • 原文地址:https://www.cnblogs.com/zxh1297/p/9353037.html
Copyright © 2011-2022 走看看