python多线程互斥锁

当两个线程同时访问同一个资源时,就容易对数据造成破坏,使得线程运行的结果不可预测:
当运算量稍大一些时
当work1和work2两个线程同时对 g_num =0 ,做循环100000次+1操作时

import threading

g_num = 0
def work1():
    global g_num
    for i in range(100000):
        g_num += 1
    print(g_num)

def work2():
   global g_num
    for i in range(100000):
        g_num += 1
    print(g_num)

if __name__ == '__main__':
    th1 = threading.Thread(target=work1)
    th2 = threading.Thread(target=work2)
    th1.start()
    th2.start()
    th1.join()
    th2.join()
    print(g_num)

正常的话两次print输出的结果应该是100000,和200000.
但实际是:
python多线程互斥锁_第1张图片
而且每次运行的结果也不相同,这是因为虽然我们在主函数中写的是work1先执行但是在work1还在执行中并未结束时,work2也同样开始了执行,这样就会导致出现错误,比如g_num此时为5000,而work1,work2同时做了+1操作,那么work1返回5001,同样work2也是返回5001,这样就相当于做了2次+1操作,结果g_num的值却只从5000变为了5001.
为避免这类情况发生有两种方法:
一:用互斥锁,这是最正规的方法

import threading

g_num = 0
def work1():
    global g_num
    lock.acquire ()
    for i in range(100000):
        g_num += 1
    lock.release()
    print(g_num)

def work2():
    global g_num
    for i in range(100000):
        lock.acquire()
        g_num += 1
        lock.release()
    print(g_num)
    
if __name__ == '__main__':
    lock = threading.Lock()
    th1 = threading.Thread(target=work1)
    th2 = threading.Thread(target=work2)
    th1.start()
    th2.start()
    th1.join()
    th2.join()
    print(g_num)

结果:
在这里插入图片描述

方法二:
直接用join()到 th2.start()之前,让 th1运行完再执行th2,当然这样不再是两个进程交替执行了,这样就不符和时间片的轮转调度,不建议这样使用。

import threading

g_num = 0
def work1():
    global g_num
    for i in range(100000):
        g_num += 1
    print(g_num)

def work2():
   global g_num
    for i in range(100000):
        g_num += 1
    print(g_num)

if __name__ == '__main__':
    th1 = threading.Thread(target=work1)
    th2 = threading.Thread(target=work2)
    th1.start()
    th1.join()
    
    th2.start()
    
    th2.join()
    print(g_num)

python多线程互斥锁_第2张图片

你可能感兴趣的:(python多线程互斥锁)