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 匹配任意字符(包括换行符)的正则表达式写法
Oct 29 Python
Python字符串处理函数简明总结
Apr 13 Python
python简单实现计算过期时间的方法
Jun 09 Python
python引入导入自定义模块和外部文件的实例
Jul 24 Python
Python多进程multiprocessing用法实例分析
Aug 18 Python
解决python通过cx_Oracle模块连接Oracle乱码的问题
Oct 18 Python
python验证身份证信息实例代码
May 06 Python
python 用 xlwings 库 生成图表的操作方法
Dec 22 Python
python实现从ftp服务器下载文件
Mar 03 Python
python字典通过值反查键的实现(简洁写法)
Sep 30 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
Nov 26 Python
使用pandas实现筛选出指定列值所对应的行
Dec 13 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跨站攻击实例分析
2014/10/28 PHP
PHP用反撇号执行外部命令
2015/04/14 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
YII2框架中查询生成器Query()的使用方法示例
2020/03/18 PHP
ie和firefox中img对象区别的困惑
2006/12/27 Javascript
加速IE的Javascript document输出的方法
2010/12/02 Javascript
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
运算符&&的三个不同层次
2013/04/07 Javascript
js弹出层包含flash 不能关闭隐藏的2种处理方法
2013/06/17 Javascript
高性能JavaScript模板引擎实现原理详解
2015/02/05 Javascript
jQuery对象初始化的传参方式
2015/02/26 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
2015/06/11 Javascript
VC调用javascript的几种方法(推荐)
2016/08/09 Javascript
Jquery组件easyUi实现表单验证示例
2016/08/23 Javascript
Bootstrap的class样式小结
2016/12/01 Javascript
jQuery.form.js的使用详解
2017/06/14 jQuery
JavaScript实现图片无缝滚动效果
2017/07/07 Javascript
JavaScript原生实现观察者模式的示例
2017/12/15 Javascript
vue递归组件实战之简单树形控件实例代码
2019/08/27 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
vue实现计算器功能
2020/02/22 Javascript
Python中使用dom模块生成XML文件示例
2015/04/05 Python
深入理解Python3中的http.client模块
2017/03/29 Python
使用Python对SQLite数据库操作
2017/04/06 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
jupyter notebook 重装教程
2020/04/16 Python
HTML5在a标签内放置块级元素示例代码
2013/08/23 HTML / CSS
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
中专毕业生自荐信范文
2013/11/28 职场文书
社会保险接收函
2014/01/12 职场文书
关于孝道的演讲稿
2014/05/21 职场文书
班级课外活动总结
2014/07/09 职场文书
三好学生事迹材料
2014/12/24 职场文书
2015年教育实习工作总结
2015/04/24 职场文书
导游词之蜀山胜景瓦屋山
2019/11/29 职场文书