Python多线程编程(二)
来源:互联网 发布:礼品卡兑换系统源码 编辑:程序博客网 时间:2024/04/30 15:09
我在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-8import threadingCOUNT = 0class 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: ',COUNTif __name__ == '__main__': for i in range(10): thread = AddUp() thread.start() thread.join() print 'COUNT: ',COUNT
运行结果如下:
[yantao@yantao thread]$ python 1.py Current result: 10000Current result: 20000Current result: 30000Current result: 40000Current result: 50000Current result: 60000Current result: 70000Current result: 80000Current result: 90000Current result: 100000COUNT: 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-8import threadingCOUNT = 0class AddUp(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global COUNT for i in xrange(10000): COUNT += 1if __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 多线程编程(二)
- python多线程编程(二)
- Python多线程编程(二)
- python多线程编程(二)--threading模块
- python多线程编程(二)--threading模块
- 多线程编程(二)
- windows多线程编程(二)
- linux 多线程编程(二)
- Linux多线程编程(二)
- Linux多线程编程(二)
- 多线程编程笔记(二)
- Linux多线程编程(二)
- Linux多线程编程(二)
- Python编程(二)
- python 多线程编程(一)
- python 多线程编程(三)
- python 多线程编程(四)
- python多线程编程(五)
- 算法导论 红黑树 学习 插入(三)
- Android 接入微信支付宝支付
- 1064.Complete Binary Search Tree (30)...to be continued...
- Error:Execution failed for task ':app:mergeDebugResources'. >\re
- ACTIVITI ACT_RU_EXECUTION Parallelgateway 旁支
- Python多线程编程(二)
- 《中文电子病历实体关系抽取研究》——笔记
- 算法提高 P1001
- 关于模板元编程的一点反思
- 何为相机OTP
- Android调试笔记——引用unity的库后,高德地图变成白屏。
- 1 vtk安装记录
- 按照已有的模板打印小票<二> ——调用windows打印机打印 可设置字体样式
- Java学习笔记