多进程中遇到的问题
以下实例中:
import threading
lock = threading.Lock()
num = 0
def work1(asd):
global num
for i in range(asd):
num += 1
print('在当前的线程修改过后的num是',num)
def work2(asd):
global num
for i in range(asd):
num += 1
print('在当前的线程修改过后的num是',num)
if __name__ == '__main__':
t1 = threading.Thread(target=work1,args=(1000000,))
t2 = threading.Thread(target=work2, args=(1000000,))
t1.start()
t2.start()
-------------------------------------------------------结果
在当前的线程修改过后的num是 1320928
在当前的线程修改过后的num是 1307852
我们发现,当给到work1与work2中的数字过大时,多线程执行完之后与我们所想要得到的结果并不一样。
这是因为线程1(work1)正在执行,但并未执行完就被线程2(work2)抢断执行,导致num在赋值的过程中并没有给到其他线程这个值,所以累加时数字重复导致得到的结果小于正确值。
为此,我们在过程中添加进程锁保证该进程执行完毕之后再交给其他线程执行
import threading
lock = threading.Lock()
num = 0
def work1(asd):
global num
for i in range(asd):
flag = lock.acquire(True)
if flag:
num += 1
lock.release()
print('在当前的线程修改过后的num是',num)
def work2(asd):
global num
for i in range(asd):
flag = lock.acquire(True)
if flag:
num += 1
lock.release()
print('在当前的线程修改过后的num是',num)
if __name__ == '__main__':
t1 = threading.Thread(target=work1,args=(1000000,))
t2 = threading.Thread(target=work2, args=(1000000,))
t1.start()
t2.start()
------------------------------------------------------结果
在当前的线程修改过后的num是 1926363
在当前的线程修改过后的num是 2000000
但互斥锁只能确保其中一个执行结果正确
互斥锁
优点:解决了资源争抢的问题
缺点:变为了单线程,可能会变成死锁