python中多线程共享全局变量的优缺点
优点:在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
缺点:线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)
下面就是一个资源竞争,全局变量混乱的例子
代码中两个线程同时对全局变量num进行了加1000000次1的操作,可结果却并非为20000000
from threading import Thread, current_thread def add_1(): global num for temp in range(1000000): num += 1 print("%s的计算结果是:%s" % (current_thread().name, num)) def main(): t_1 = Thread(target=add_1) t_2 = Thread(target=add_2) t_1.start() t_2.start() t_1.join() t_2.join() print("num的最终结果是:%s" % num) if __name__ == '__main__': num = 0 main()
Thread-1的计算结果是:1151125 Thread-2的计算结果是:1299192 num的最终结果是:1299192
解决的办法:可以在线程对全局变量操作的地方添加一个互斥锁.
上锁的过程:
当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“阻塞”,直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态
from threading import Thread, current_thread,Lock def add_1(): global num lock.acquire() for temp in range(1000000): num += 1 lock.release() print("%s的计算结果是:%s" % (current_thread().name, num)) def main(): t_1 = Thread(target=add_1) t_2 = Thread(target=add_1) t_1.start() t_2.start() t_1.join() t_2.join() print("num的最终结果是:%s" % num) if __name__ == '__main__': lock = Lock() num = 0 main()