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 15 Python
Python调用命令行进度条的方法
May 05 Python
Python简单实现安全开关文件的两种方式
Sep 19 Python
numpy使用技巧之数组过滤实例代码
Feb 03 Python
python matlibplot绘制多条曲线图
Feb 19 Python
python3爬虫获取html内容及各属性值的方法
Dec 17 Python
Python之使用adb shell命令启动应用的方法详解
Jan 07 Python
python3转换code128条形码的方法
Apr 17 Python
Pycharm运行加载文本出现错误的解决方法
Jun 27 Python
Python单元测试与测试用例简析
Nov 09 Python
python如何删除列为空的行
Jul 17 Python
Python GUI编程之tkinter 关于 ttkbootstrap 的使用详解
Mar 03 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
德生H-501的评价与改造
2021/03/02 无线电
咖啡与水的关系
2021/03/03 冲泡冲煮
获得Google PR值的PHP代码
2007/01/28 PHP
php 连接mssql数据库 初学php笔记
2010/03/01 PHP
PHP SPL使用方法和他的威力
2013/11/12 PHP
PHP彩蛋信息介绍和阻止泄漏的方法(隐藏功能)
2014/08/06 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
JavaScript事件委托技术实例分析
2015/02/06 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
jquery序列化方法实例分析
2015/06/10 Javascript
jquery实现鼠标滑过小图查看大图的方法
2015/07/20 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
JavaScript随机生成颜色的方法
2016/10/15 Javascript
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
vue 动态给每个页面添加title、关键词和描述的方法
2020/08/28 Javascript
[50:11]2018DOTA2亚洲邀请赛 4.7总决赛 LGD vs Mineski 第三场
2018/04/09 DOTA
python邮件发送smtplib使用详解
2020/06/16 Python
python实现换位加密算法的示例
2018/10/14 Python
与Django结合利用模型对上传图片预测的实例详解
2019/08/07 Python
python 实现一个反向单位矩阵示例
2019/11/29 Python
Python利用逻辑回归模型解决MNIST手写数字识别问题详解
2020/01/14 Python
Python字符串中删除特定字符的方法
2020/01/15 Python
如何利用python之wxpy模块玩转微信
2020/08/17 Python
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
Europcar西班牙:全球汽车租赁领域的领导者
2018/09/17 全球购物
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
航空大学应届生求职信
2013/11/10 职场文书
幼儿园家长评语
2014/02/10 职场文书
2014厂务公开实施方案
2014/02/17 职场文书
党员批评与自我批评思想汇报
2014/10/08 职场文书
党的群众路线教育实践活动整改方案
2014/10/28 职场文书
西安大雁塔导游词
2015/02/10 职场文书
开学第一周总结
2015/07/16 职场文书
MySQL命令无法输入中文问题的解决方式
2021/08/30 MySQL
SpringBoot集成MongoDB实现文件上传的步骤
2022/04/18 MongoDB