本文实例讲述了Python多线程原理与用法。分享给大家供大家参考,具体如下:
先来看个栗子:
下面来看一下I/O秘籍型的线程,举个栗子——爬虫,下面是爬下来的图片用4个线程去写文件
#!/usr/bin/env python# -*- coding:utf-8 -*-import reimport urllibimport threadingimport Queueimport timeitdef getHtml(url): html_page = urllib.urlopen(url).read() return html_page# 提取网页中图片的URLdef getUrl(html): pattern = r'src="(http://img.*?)"' # 正则表达式 imgre = re.compile(pattern) imglist = re.findall(imgre, html) # re.findall(pattern,string) 在string中寻找所有匹配成功的字符串,以列表形式返回值 return imglistclass getImg(threading.Thread): def __init__(self, queue, thread_name=0): # 线程公用一个队列 threading.Thread.__init__(self) self.queue = queue self.thread_name = thread_name self.start() # 启动线程 # 使用队列实现进程间通信 def run(self): global count while (True): imgurl = self.queue.get() # 调用队列对象的get()方法从队头删除并返回一个项目 urllib.urlretrieve(imgurl, 'E:/mnt/girls/%s.jpg' % count) count += 1 if self.queue.empty(): break self.queue.task_done() # 当使用者线程调用 task_done() 以表示检索了该项目、并完成了所有的工作时,那么未完成的任务的总数就会减少。imglist = []def main(): global imglist url = "http://huaban.com/favorite/beauty/" # 要爬的网页地址 html = getHtml(url) imglist = getUrl(html)def main_1(): global count threads = [] count = 0 queue = Queue.Queue() # 将所有任务加入队列 for img in imglist: queue.put(img) # 多线程爬去图片 for i in range(4): thread = getImg(queue, i) threads.append(thread) # 阻塞线程,直到线程执行完成 for thread in threads: thread.join()if __name__ == '__main__': main() t = timeit.Timer(main_1) print t.timeit(1)
4个线程的执行耗时为:0.421320716723秒
修改一下main_1换成单线程的:
def main_1(): global count threads = [] count = 0 queue = Queue.Queue() # 将所有任务加入队列 for img in imglist: queue.put(img) # 多线程爬去图片 for i in range(1): thread = getImg(queue, i) threads.append(thread) # 阻塞线程,直到线程执行完成 for thread in threads: thread.join()
单线程的执行耗时为:1.35626623274秒
再来看一个:
#!/usr/bin/env python# -*- coding:utf-8 -*-import threadingimport timeitdef countdown(n): while n > 0: n -= 1def task1(): COUNT = 100000000 thread1 = threading.Thread(target=countdown, args=(COUNT,)) thread1.start() thread1.join()def task2(): COUNT = 100000000 thread1 = threading.Thread(target=countdown, args=(COUNT // 2,)) thread2 = threading.Thread(target=countdown, args=(COUNT // 2,)) thread1.start() thread2.start() thread1.join() thread2.join()if __name__ == '__main__': t1 = timeit.Timer(task1) print "countdown in one thread ", t1.timeit(1) t2 = timeit.Timer(task2) print "countdown in two thread ", t2.timeit(1)
新闻热点
疑难解答