(2018-04-10.Python从Zero到One)二、python高级编程__2.2.5同步的概念

上一篇文章为:→2.1.4多进程修改全局变量

同步的概念

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进行修改时,都要先上锁,处理完后再解锁,在上锁的整个过程中不允许其他线程访问,就保证了数据的正确性


下一篇文章为:→2.2.6互斥锁

你可能感兴趣的:((2018-04-10.Python从Zero到One)二、python高级编程__2.2.5同步的概念)