🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
同步的概念 1. 多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改10次,num的最终的结果应该为20。 但是由于是多线程访问,有可能出现下面情况: 在num=0时,t1取得num=0。此时系统把t1调度为”sleeping”状态,把t2转换为”running”状态,t2也获得num=0。然后t2对得到的值进行加1并赋给num,使得num=1。然后系统又把t2调度为”sleeping”,把t1转为”running”。线程t1又把它之前得到的0加1后赋值给num。这样,明明t1和t2都完成了1次加1工作,但结果仍然是num=1。 ~~~ from threading import Thread import time g_num = 0 def test1(): global g_num for i in range(1000000): g_num += 1 print("---test1---g_num=%d"%g_num) def test2(): global g_num for i in range(1000000): g_num += 1 print("---test2---g_num=%d"%g_num) p1 = Thread(target=test1) p1.start() # time.sleep(3) #取消屏蔽之后 再次运行程序,结果会不一样,,,为啥呢? p2 = Thread(target=test2) p2.start() print("---g_num=%d---"%g_num) ~~~ 运行结果(可能不一样,但是结果往往不是2000000): ~~~ ---g_num=284672--- ---test1---g_num=1166544 ---test2---g_num=1406832 ~~~ 取消屏蔽之后,再次运行结果如下: ---test1---g_num=1000000 ---g_num=1041802--- ---test2---g_num=2000000 问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。 2. 什么是同步 同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。 "同"字从字面上容易理解为一起动作 其实不是,"同"字应是指协同、协助、互相配合。 如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 3. 解决问题的思路 对于本小节提出的那个计算错误的问题,可以通过线程同步来进行解决 思路,如下: 1. 系统调用t1,然后获取到num的值为0,此时上一把锁,即不允许其他现在操作num 2. 对num的值进行+1 3. 解锁,此时num的值为1,其他的线程就可以使用num了,而且是num的值不是0而是1 4. 同理其他线程在对num进行修改时,都要先上锁,处理完后再解锁,在上锁的整个过程中不允许其他线程访问,就保证了数据的正确性