python多线程编程特别适用于完成相互独立的任务,同时进行,相互之间没有依赖性。比如,下面我们介绍的从网站中查询每本书的排名这个任务,就非常适合应用多线程来提升效率。
1 理论分析
单线程情况下,查询n本书的排名,需要执行n次排名查询。
多线程情况下,同时对每一本书的排名进行查询,无需顺序执行。
2 代码实现
2.1 单线程的代码实现bookrank.py
#!/usr/bin/env python
# coding=utf-8
# import pdb
from atexit import register
from re import compile
from threading import Thread
from time import ctime
from urllib2 import urlopen as uopen
REGEX = compile('#([\d,]+) in Books')
AMZN = 'http://amazon.com/dp/'
ISBNs = {
'0132269937':'Core Python Programming',
'0132356139':'Python web Development with Djanjo',
'0137143419':'Python Fundamentals',
}
def getRanking(isbn):
page = uopen('%s%s' % (AMZN,isbn))
data = page.read()
page.close()
return REGEX.findall(data)[0]
def _showRanking(isbn):
print '- %r ranked %s' %(ISBNs[isbn],getRanking(isbn))
def main():
print 'At', ctime(), 'On Amazon...'
# pdb.set_trace()
for isbn in ISBNs:
_showRanking(isbn)
@register
def _atexit():
print 'ALL DONE at:', ctime()
if __name__ == '__main__':
main()
运行结果分析:
单线程用时20s。
2.2 多线程的代码实现 bookrank_mts.py
#!/usr/bin/env python
# coding=utf-8
# import pdb
from atexit import register
from re import compile
from threading import Thread
from time import ctime
from urllib2 import urlopen as uopen
REGEX = compile('#([\d,]+) in Books')
AMZN = 'http://amazon.com/dp/'
ISBNs = {
'0132269937':'Core Python Programming',
'0132356139':'Python web Development with Djanjo',
'0137143419':'Python Fundamentals',
}
def getRanking(isbn):
page = uopen('%s%s' % (AMZN,isbn))
data = page.read()
page.close()
return REGEX.findall(data)[0]
def _showRanking(isbn):
print '- %r ranked %s' %(ISBNs[isbn],getRanking(isbn))
def main():
print 'At', ctime(), 'On Amazon...'
# pdb.set_trace()
for isbn in ISBNs:
Thread(target=_showRanking, args=(isbn,)).start()
@register
def _atexit():
print 'ALL DONE at:', ctime()
if __name__ == '__main__':
main()
多线程用时6s。
3 结果分析
分析结果,我们会发现,对于这种多任务不具关联性的情况,采用多线程会明显节省时间,效率大大提高,我们仅仅举了一个查询3本书的排名就省了十几秒,如果要查更多的书,效果会更明显。