使用Python进行线程编程(1)

Tag:Python 队列 线程
在实习中学习了Python,到现在不大两个月,写了个1000行的脚本,但是多线程效率太低,固有此文,如果错误,敬请指正。

这是看一篇文章:http://www.ibm.com/developerworks/cn/aix/library/au-threadingpython/?ca=drs-tp3008后的吸收和笔记,原文信息非常多,推荐原文。

简介:通过将线程和队列结合在一起,创建一些简单有效的模式,以解决需要并发处理的问题。

效果就像学校食堂排队打饭一样,大妈手里的勺子不会歇着。

1、简单的多个线程处理:

View Code
 1 import threading
2 import datetime
3
4 class ThreadClass(threading.Thread):
5 def run(self):
6 now = datetime.datetime.now()
7 print "%s says Hello World at time: %s" %
8 (self.getName(), now)
9
10 for i in range(2):
11 t = ThreadClass()
12 t.start()

第七行代码打错了,不应该换行,这个是原文粘贴过来的
定义了一个继承自threading.Thread的类,重定义了run()方法,即启动线程后要处理的事情,然后启动两个线程知道任务处理完成。

2、以处理大量URL为例,这次放上整个例子,原文的代码有点乱,我稍作了整理:
只是不好意思,我写的有点拖沓
注释:为了处理一个URL队列,定义了两个继承自threading.Thread的类,重定义了__init__()和run()方法
ThreadURL:这个线程类用来从队列中取出一个URL生成BS包,把处理结果保存到out_queue中
ThreadPrint:用来处理ThreadURL保存到out_queue的结果,原理与ThreadURL一样
第一个函数:GetBSFromURL(),用来从URL生成BeautifulSoup包
流程:
定义两个队列,queue用来保存要处理的任务,out_queue用来保存处理结果,处理结果也要用队列线程处理
启动5个线程ThreadURL,初始化,生成守护线程池,启动线程,每个线程处理完成时,通过queue的task_done()向队列发送一个处理完成信号,可以处理下一个任务,这样轮番处理queue中的URL
开始向queue队列填充要处理的任务列表
启动m个线程ThreadPrint,用来处理结果,方法同上
queue.join()
out_queue.join()
等待队列为空,所有任务处理完成,程序退出

View Code
 1 # -*- coding:utf-8 -*-
2 '''
3 Created on Oct 8, 2011
4
5 @author: Lannik Cooper
6 '''
7 import urllib2
8 from BeautifulSoup import BeautifulSoup
9 import json
10 import time
11 import threading
12 from mx import DateTime
13 import Queue
14
15 def GetBSFromURL(url):
16 soup=None
17 while True:
18 try:
19 f=urllib2.urlopen(url)
20 if f!=None:
21 soup=BeautifulSoup(f)
22 f.close()
23 if soup!=None:
24 break
25 pass
26 except:
27 time.sleep(3)
28 pass
29 pass
30 return soup
31
32
33 class ThreadURL(threading.Thread):
34 def __init__(self,queue,out_queue):
35 threading.Thread.__init__(self)
36 self.queue=queue
37 self.out_queue=out_queue
38 pass
39
40 def run(self):
41 while True:
42 host=self.queue.get()
43 soup=GetBSFromURL(host)
44 self.out_queue.put(soup)
45 self.queue.task_done()
46 pass
47 pass
48
49 class ThreadPrint(threading.Thread):
50 def __init__(self,out_queue):
51 threading.Thread.__init__(self)
52 self.out_queue=out_queue
53 pass
54 def run(self):
55 while True:
56 soup=self.out_queue.get()
57 print soup.title.text
58 self.out_queue.task_done()
59 pass
60 pass
61 pass
62
63 def main():
64 hosts=["http://google.com.hk", "http://t.qq.com", "http://amazon.cn","http://www.baidu.com", "http://t.sina.com"]
65 start=time.time()
66 queue=Queue.Queue()
67 out_queue=Queue.Queue()
68 for i in range(5):
69 t=ThreadURL(queue,out_queue)
70 t.setDaemon(True)
71 t.start()
72 pass
73 for host in hosts:
74 queue.put(host)
75 pass
76 for i in range(1):
77 t=ThreadPrint(out_queue)
78 t.setDaemon(True)
79 t.start()
80 pass
81 queue.join()
82 out_queue.join()
83 print "Elapsed Time: %s" % (time.time() - start)
84 pass
85
86 main()

这样就完成了线程结合队列进行多线程处理。

 

问题:
由于看的时间很短,原文备注中提到的文章还没来得及看,所以很多东西还是不清楚,比如Thread的setDaemon(),守护线程池的作用不是很清楚。
待有所获后再补一篇文章。

现在正是校园招聘火热期,时间很纠结,GDT要用好。
待续。。。

posted @ 2011-10-11 21:15  L Cooper  阅读(536)  评论(0编辑  收藏  举报