Python多线程编程(二)

我在Python多线程编程(一) 这篇文章中记录了一下threading模块的常用方法和两种写run()函数的方法。这篇文章写一下自己遇到过的几个问题,通过实例重新理解下join()函数,以及多线程修改全局变量时的坑。

首先明确下下join()函数的作用:主线程A中创建了一个子线程B,并且在主线程中调用B.join()方法。那么主线程就会在调用B.join()这个地方等待,直到子线程B完成操作或者子线程B超时,主线程A才可以继续往下面执行其他语句

1. 每个线程操作一个全局变量进行累加,最后结果应该是什么?

下面代码中用了10个线程去执行一个10000 次的for循环,以此累加**COUNT **这个全局变量,我们COUNT值累加后会是10000吗?或者是其他的值?

脚本 1.py

[yantao@yantao thread]$ cat 1.py 
#/usr/bin/python
#coding: utf-8

import threading

COUNT = 0

class AddUp(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        global COUNT
        for i in xrange(10000):
            COUNT += 1
        print 'Current result: ',COUNT

if __name__ == '__main__':
    for i in range(10):
        thread = AddUp()
        thread.start()
        thread.join()
    print 'COUNT: ',COUNT

运行结果如下:

[yantao@yantao thread]$ python 1.py 
Current result:  10000
Current result:  20000
Current result:  30000
Current result:  40000
Current result:  50000
Current result:  60000
Current result:  70000
Current result:  80000
Current result:  90000
Current result:  100000
COUNT:  100000

最后的结果是100000,和“预期”结果相符合。但是,事实并不是这样的,我们的目的是10个线程并发累加得到COUNT的值1.py 脚本虽然在主线程中又产生了10个线程,但实际上这10个线程是串行的,并不是并行的!
  为什么呢?来分析下产生线程的代码:

if __name__ == '__main__':
    for i in range(10):
        thread = AddUp()
        thread.start()
        thread.join()
    print 'COUNT: ',COUNT

我们观察到子线程thread在start()后,我们在主线程中立刻调用了thread线程的join()函数,以此来阻塞当前线程(主线程)。那么我们的主线程就会停留在join()函数这里,直到子线程返回结果后,主线程才会继续执行for循环产生新的线程,但是我们继续调用了新线程的join()方法,主线程会继续等待直到新的子线程返回结果才会继续执行。如此反复10次。从这个逻辑可以看出,这里并没有并发,只不过是用了10个线程分别循环10000次,做了主线程循环100000次就可以做到的事情。 那么如何做到并发了?只要对1.py稍作更改即可,如下2.py

脚本 2.py

#/usr/bin/python
#coding: utf-8

import threading

COUNT = 0

class AddUp(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        global COUNT         
        for i in xrange(10000):
            COUNT += 1

if __name__ == '__main__':
    threads = []
    for i in range(10):
        thread = AddUp()
        #print thread.getName()
        threads.append(thread)      #将所有子线程放在一个列表里面
        thread.start()                       #线程执行后不阻塞主线程,继续执行for循环产生新的线程
    for thread in threads:              #在此处阻塞主线程,直到所有子线程返回
        thread.join()
    print COUNT

多次运行程序看下结果:

[yantao@yantao thread]$ python 2.py 
53359
[yantao@yantao thread]$ python 2.py 
47909
[yantao@yantao thread]$ python 2.py 
52725

从结果看每次运行的并不一样,这说明这里确实是并发了,但是为什么值会不一样了?因为多个线程操作一个全局变量时,会发生资源抢占,变量不能按照预定的逻辑进行操作,比如我们这里得到得结果就不是100000.
  在使用多线程时,尽量避免操作全局变量,以免引发不必要得麻烦,如果非要用,应该做好锁机制。

你可能感兴趣的:(Python多线程编程(二))