异想天开

What's the true meaning of light, Could you tell me why

python多线程编程

日期:2015-06-24 10:37:52
  
最后更新日期:2015-06-25 15:26:46
python多线程通信包含如下模块:
[code lang="cpp"]
import threading //线程模块,互斥锁
import Queue //消息通信
[/code]
threading模块是python封装的面向对象的线程模块,还一个面向过程的模块名为thread。当时使用threading而没有使用thread模块,竟然是因为thread里面不知道怎么线程join。囧。

测试线程调度的例子:
[code lang="cpp"]
#!/usr/bin/python
# encoding: utf-8
import MySQLdb
import sys
import traceback
import threading
import Queue
import time

remote_movie_host=''
remote_movie_port=3306
remote_movie_passwd=''
remote_movie_dbname=''
remote_movie_user=''

#remote_db=MySQLdb.connect(host=remote_movie_host,user=remote_movie_user,passwd=remote_movie_passwd,db=remote_movie_dbname,port=remote_movie_port)

def test():
print 'hello world'

def thread_main(id):
for i in range(10):
print "I am thread %d " % id

if __name__=='__main__':
pool=[]
try:
for id in range(5):
t=threading.Thread(target=thread_main,name="%d"%id,args=(id,))
t.start()
pool.append(t)
for t in pool:
t.join()
except Exception,e:
print traceback.format_exc()

[/code]
执行结果:
1.在我阿里云单核机器上的结果为:
I am thread 0
*
I am thread 1
*
I am thread 2
*
I am thread 3
*
I am thread 4
*
而不论我增加打印次数到100时,还是一样按线程创建顺序结束,why?
原因为:
在阿里云利用strace -f python demo.py跟踪执行,发现实际上创建了线程,对于print不过输出到内存里面,但在执行过程中发现先创建的线程先结束(在这里是这样的),然后线程结束刷新到屏幕。所以按顺序显示了。若在print后面加上sys.stdout.flush()则可以看到乱序显示了。
前面没有加sys.stdou.flush()不涉及到io操作,可以认为都是计算型的,很快执行完了,所以先创建的会先结束。其实这里最主要的是打印的东西,太少了,若100改为10000,也会乱序显示,因为print超过指定的缓存大小,会强制刷向stdout输出屏幕的,结果就看到乱序显示的。

观察可以得出另外一个结论:
这里多线程即使在多核环境下也会退化为单核模式,因为python解释器只有一个,同一时刻只能对一个线程的代码解释,strace跟踪也发现了futex调用,应该是实现GIL机制的。

2.在公司多核机器上执行,显示结果无顺序

而queue使用方法:
[code lang="cpp"]
#msg_queue的get操作
try:
msg=msg_queue.get(block=false)
except Queue.Empty:
pass
else:
dosomethingelse()
#msg_queue的put操作
msg_queue.put(msg)
[/code]

参考:
1.python线程调度