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实现的DES加密算法和3DES加密算法实例
Jun 03 Python
详解Python的Twisted框架中reactor事件管理器的用法
May 25 Python
python模拟事件触发机制详解
Jan 19 Python
python保存网页图片到本地的方法
Jul 24 Python
python3 中文乱码与默认编码格式设定方法
Oct 31 Python
python实现二维数组的对角线遍历
Mar 02 Python
python简单验证码识别的实现方法
May 10 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 Python
Python任务调度模块APScheduler使用
Apr 15 Python
python实现剪贴板的操作
Jul 01 Python
Python多个MP4合成视频的实现方法
Jul 16 Python
python中 .npy文件的读写操作实例
Apr 14 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
神族 Protoss 历史背景
2020/03/14 星际争霸
php 日期和时间的处理-郑阿奇(续)
2011/07/04 PHP
php使用exec shell命令注入的方法讲解
2013/11/12 PHP
php算法实例分享
2015/07/14 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
2016/02/15 PHP
用javascript编写的第一人称射击游戏
2007/02/25 Javascript
javascript SocialHistory 检查访问者是否访问过某站点
2008/08/02 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
javascript面向对象程序设计(一)
2015/01/29 Javascript
四种参数传递的形式——URL,超链接,js,form表单
2015/07/24 Javascript
jQuery采用连缀写法实现的折叠菜单效果
2015/09/18 Javascript
JavaScript模拟push
2016/03/06 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
在JavaScript中使用严格模式(Strict Mode)
2019/06/13 Javascript
Layui Table js 模拟选中checkbox的例子
2019/09/03 Javascript
在vue中把含有html标签转为html渲染页面的实例
2019/10/28 Javascript
Vue toFixed保留两位小数的3种方式
2020/10/23 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
python基于multiprocessing的多进程创建方法
2015/06/04 Python
Python的网络编程库Gevent的安装及使用技巧
2016/06/24 Python
详解Appium+Python之生成html测试报告
2019/01/04 Python
python 通过麦克风录音 生成wav文件的方法
2019/01/09 Python
python实现维吉尼亚算法
2019/03/20 Python
关于Python中的向量相加和numpy中的向量相加效率对比
2019/08/26 Python
Python计算两个矩形重合面积代码实例
2019/09/16 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
如何卸载python插件
2020/07/08 Python
django跳转页面传参的实现
2020/09/17 Python
英文导游欢迎词
2014/01/11 职场文书
同学会主持词
2014/03/18 职场文书
计划生育宣传标语
2014/06/21 职场文书
医院保洁员岗位职责
2015/02/13 职场文书
支教个人总结
2015/03/04 职场文书
水知道答案观后感
2015/06/08 职场文书
PyTorch的Debug指南
2021/05/07 Python