Python 多线程抓取图片效率对比


Posted in Python onFebruary 27, 2016

目的:

是学习python 多线程的工作原理,及通过抓取400张图片这种IO密集型应用来查看多线程效率对比

import requests
import urlparse
import os
import time
import threading
import Queue

path = '/home/lidongwei/scrapy/owan_img_urls.txt'
#path = '/home/lidongwei/scrapy/cc.txt'
fetch_img_save_path = '/home/lidongwei/scrapy/owan_imgs/'

# 读取保存再文件里面400个urls
with open(path) as f :
  urls = f.readlines()

urls = urls[:400]
# 使用Queue来线程通信,因为队列是线程安全的(就是默认这个队列已经有锁)
q = Queue.Queue()
for url in urls:
  q.put(url)

start = time.time()

def fetch_img_func(q):
  while True:
    try:
      # 不阻塞的读取队列数据
      url = q.get_nowait()
      i = q.qsize()
    except Exception, e:
      print e
      break;
    print 'Current Thread Name Runing %s ... 11' % threading.currentThread().name
    url = url.strip()
    img_path = urlparse.urlparse(url).path
    ext = os.path.splitext(img_path)[1]
    print 'handle %s pic... pic url %s ' % (i, url)
    res = requests.get(url, stream=True)

    if res.status_code == 200:
      save_img_path = '%s%s%s' % (fetch_img_save_path, i, ext)
      # 保存下载的图片
      with open(save_img_path, 'wb') as fs:
        for chunk in res.iter_content(1024):
          fs.write(chunk)
        print 'save %s pic ' % i

# 可以开多个线程测试不同效果
t1 = threading.Thread(target=fetch_img_func, args=(q, ), name="child_thread_1")
#t2 = threading.Thread(target=fetch_img_func, args=(q, ), name="child_thread_2")
#t3 = threading.Thread(target=fetch_img_func, args=(q, ), name="child_thread_3")
#t4 = threading.Thread(target=fetch_img_func, args=(q, ), name="child_thread_4")
t1.start()
#t2.start()
#t3.start()
#t4.start()
t1.join()
#t2.join()
#t3.join()
#t4.join()

end = time.time()
print 'Done %s ' % (end-start)

实验结果

400图片

4线程 Done 12.443133831
3线程 Done 12.9201757908 
2线程 Done 32.8628299236
1线程 Done 54.6115460396

总结

Python 自带GIL 大锁, 没有真正意义上的多线程并行执行。GIL 大锁会在线程阻塞的时候释放,此时等待的线程就可以激活工作,这样如此类推,大大提高IO阻塞型应用的效率。

Python 相关文章推荐
Python深入学习之上下文管理器
Aug 31 Python
Python解析网页源代码中的115网盘链接实例
Sep 30 Python
Python2/3中urllib库的一些常见用法
Dec 19 Python
Python机器学习k-近邻算法(K Nearest Neighbor)实例详解
Jun 25 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
Jul 07 Python
对python产生随机的二维数组实例详解
Dec 13 Python
Python 脚本实现淘宝准点秒杀功能
Nov 13 Python
Django后端发送小程序微信模板消息示例(服务通知)
Dec 17 Python
Python进阶之迭代器与迭代器切片教程
Jan 29 Python
vue常用指令代码实例总结
Mar 16 Python
Python判断字符串是否为空和null方法实例
Apr 26 Python
Python timeit模块原理及使用方法
Oct 10 Python
Python 的描述符 descriptor详解
Feb 27 #Python
简析Python的闭包和装饰器
Feb 26 #Python
Android应用开发中Action bar编写的入门教程
Feb 26 #Python
12步教你理解Python装饰器
Feb 25 #Python
Python实现字典依据value排序
Feb 24 #Python
Python中方法链的使用方法
Feb 23 #Python
python开发之list操作实例分析
Feb 22 #Python
You might like
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
php实现MySQL数据库备份与还原类实例
2014/12/09 PHP
PHP实现活动人选抽奖功能
2017/04/19 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
js文字滚动停顿效果代码
2008/06/28 Javascript
一个cssQuery对象 javascript脚本实现代码
2009/07/21 Javascript
JS获取input file绝对路径的方法(推荐)
2016/08/02 Javascript
jquery中用函数来设置css样式
2016/12/22 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
2017/04/24 Javascript
原生js实现简单的链式操作
2017/07/04 Javascript
浅谈JS对象添加getter与setter的5种方法
2018/06/09 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
JS深入学习之数组对象排序操作示例
2020/05/01 Javascript
8个非常实用的Vue自定义指令
2020/12/15 Vue.js
Python中的jquery PyQuery库使用小结
2014/05/13 Python
python的文件操作方法汇总
2017/11/10 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
2018/12/12 Python
使用python来调用CAN通讯的DLL实现方法
2019/07/03 Python
使用python实现回文数的四种方法小结
2019/11/24 Python
Python远程方法调用实现过程解析
2020/07/28 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
JACK & JONES英国官方网站:欧洲领先的男装生产商
2017/09/27 全球购物
老板电器官方购物商城:老板油烟机、燃气灶、消毒柜、电烤箱
2018/05/30 全球购物
Python面试题集
2012/03/08 面试题
求职信名称怎么写
2014/05/26 职场文书
多媒体教室标语
2014/06/26 职场文书
高中教师先进事迹材料
2014/08/22 职场文书
活动总结新闻稿
2014/08/30 职场文书
防灾减灾活动总结
2014/08/30 职场文书
周年庆典答谢词
2015/01/20 职场文书
嘉宾邀请函
2015/01/31 职场文书
用Python实现Newton插值法
2021/04/17 Python
vue 实现上传组件
2021/05/31 Vue.js
Python编解码问题及文本文件处理方法详解
2021/06/20 Python
浅谈spring boot使用thymeleaf版本的问题
2021/08/04 Java/Android
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记