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字符串和文件操作常用函数分析
Apr 08 Python
Python解析nginx日志文件
May 11 Python
Python中Django框架下的staticfiles使用简介
May 30 Python
Python中对象迭代与反迭代的技巧总结
Sep 17 Python
浅谈python中的数字类型与处理工具
Aug 02 Python
python日期时间转为字符串或者格式化输出的实例
May 29 Python
python远程连接MySQL数据库
Apr 19 Python
Python字典底层实现原理详解
Dec 18 Python
git查看、创建、删除、本地、远程分支方法详解
Feb 18 Python
DjangoWeb使用Datatable进行后端分页的实现
May 18 Python
Python如何给函数库增加日志功能
Aug 04 Python
Python内置数据结构列表与元组示例详解
Aug 04 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
重置版游戏视频
2020/04/09 魔兽争霸
php XPath对XML文件查找及修改实现代码
2011/07/27 PHP
浅析php变量作用域的一些问题
2013/08/08 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
php实现断点续传大文件示例代码
2020/06/19 PHP
jQuery 改变CSS样式基础代码
2010/02/11 Javascript
ExtJS下书写动态生成的xml(兼容火狐)
2013/04/02 Javascript
复制js对象方法(详解)
2013/07/08 Javascript
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
探讨jQuery的ajax使用场景(c#)
2013/12/03 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
2016/01/26 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
利用Plupload.js解决大文件上传问题, 带进度条和背景遮罩层
2017/03/15 Javascript
Vue resource中的GET与POST请求的实例代码
2017/07/21 Javascript
详解vue2.0+vue-video-player实现hls播放全过程
2018/03/02 Javascript
Element Dialog对话框的使用示例
2020/07/26 Javascript
Python 开发Activex组件方法
2009/11/08 Python
python三元运算符实现方法
2013/12/17 Python
Python中元组,列表,字典的区别
2017/05/21 Python
python+matplotlib演示电偶极子实例代码
2018/01/12 Python
对Python中的@classmethod用法详解
2018/04/21 Python
django mysql数据库及图片上传接口详解
2019/07/18 Python
python实现桌面气泡提示功能
2019/07/29 Python
python 等差数列末项计算方式
2020/05/03 Python
英国第一独立滑雪板商店:The Snowboard Asylum
2020/01/16 全球购物
介绍一下Make? 为什么使用make
2013/12/08 面试题
高一家长会邀请函
2014/01/12 职场文书
化妆品促销方案
2014/02/24 职场文书
学生会主席竞聘书
2014/03/31 职场文书
求职信怎么写范文
2014/05/26 职场文书
幼儿园安全责任书范本
2014/07/24 职场文书
会议接待欢迎标语
2014/10/08 职场文书
2014年信用社工作总结
2014/11/25 职场文书
公务员年度考核评语
2014/12/31 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
门卫管理制度范本
2015/08/05 职场文书