网络编程-线程-6、互斥锁解决线程中数据安全问题

前沿:上一节说到多个线程之间共享全局变量会存在一个问题:资源争抢,数据混乱不安全。这一节就是如何解决共享全局变量时数据不安全的问用到的知识点:互斥锁,threading模块中有个Lock类,可以创建一个锁对象,调用acquire方法(给线程上锁)和release方法(给线程释放锁),这样就可以解决资源争抢问题了

1、那么什么叫互斥锁?它的工作原理是什么样的?还是画图说明:



2、以下面具体代码为例,
下面例子的大概意思就是,创建俩个线程函数,,每个线程函数都是修改全局变量,然后给每个线程函数上锁,解锁:
import threading
import time

"""前沿:上一节说到多个线程之间共享全局变量会存在一个问题:资源争抢,数据混乱不安全
        这一节就是如何解决共享全局变量时数据不安全的问题
   用到的知识点:互斥锁,threading模块中有个Lock类,可以创建一个锁对象,
                调用acquire方法(给线程上锁)和release方法(给线程释放锁),这样就可以解决资源争抢问题了
"""

# 下面例子的大概意思就是,创建俩个线程函数,,每个线程函数都是修改全局变量,然后给每个线程函数上锁,解锁
num = 0
muter = threading.Lock()  # 创建一个锁对象
def test1(temp):
    global  num
    muter.acquire()  # 将线程函数test1修改全局变量值得代码进行上锁
    for i in range(temp):
        num += 1
    muter.release()  # 将线程函数test1修改全局变量值得代码进行解锁
    print('test1-num:%d' % num)

def test2(temp):
    global  num
    muter.acquire()  # 将线程函数test2修改全局变量值得代码进行上锁
    for i in range(temp):
        num += 1
    muter.release()  # 将线程函数test2修改全局变量值得代码进行解锁
    print('test1-num:%d' % num)

def main():
    t1 = threading.Thread(target=test1, args=(1000000,))
    t2 = threading.Thread(target=test2, args=(1000000,))
    t1.start()
    t2.start()
    time.sleep(1)
    print('num:%d' % num)
if __name__ == '__main__':
    main()

运行结果如下:

test1-num:1000000
test1-num:2000000
num:2000000

 

如果没有加互斥锁的话,运行结果每次都是混乱的,如下:

test1-num:1129808
test1-num:1235738
num:1235738

注意点:用互斥锁时,也容易造成死锁,死锁就是:加入线程a等待线程b释放锁,线程b也在等待线程a释放锁,这就造成死锁,解决死锁的方法就是添加一个超时等待时间
下一节讲进程系列的知识。。。。。。。。。


原文地址:https://www.cnblogs.com/lz-tester/p/9357131.html