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

 更新时间:2016年02月27日 09:27:05   投稿:hebedich  
Python由于有全锁局的存在,并不能利用多核优势。所以,如果你的多线程进程是CPU密集型的,那多线程并不能带来效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。

目的:

是学习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中使用AOP实现Redis缓存示例

    在Python中使用AOP实现Redis缓存示例

    本篇文章主要介绍了在Python中使用AOP实现Redis缓存示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • OpenCV 图像梯度的实现方法

    OpenCV 图像梯度的实现方法

    梯度简单来说就是求导。本文主要介绍了OpenCV 图像梯度的实现方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Python tkinter三种布局实例详解

    Python tkinter三种布局实例详解

    这篇文章主要介绍了Python tkinter三种布局实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • pyinstaller封装exe的操作

    pyinstaller封装exe的操作

    这篇文章主要介绍了pyinstaller封装exe的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Python二叉树初识(新手也秒懂!)

    Python二叉树初识(新手也秒懂!)

    二叉树是一种简单的树形结构,其每个节点的分支节点数有0,1或2个,下面这篇文章主要给大家介绍了关于Python二叉树的相关资料,本文介绍的非常通俗易懂,新手也秒懂,需要的朋友可以参考下
    2022-05-05
  • PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例

    PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例

    今天小编就为大家分享一篇关于PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • Python 图像处理之PIL库详解用法

    Python 图像处理之PIL库详解用法

    对于图像识别,大量的工作在于图像的处理,处理效果好,那么才能很好地识别,因此,良好的图像处理是识别的基础。在Python中,有一个优秀的图像处理框架,就是PIL库,本文会介绍PIL库中的各种方法,并列举相关例子
    2021-11-11
  • SQLAlchemy的主要组件详细讲解

    SQLAlchemy的主要组件详细讲解

    SQLAlchemy是一个基于Python实现的ORM框架,能满足大多数数据库操作需求,同时支持多种数据库引擎(SQLite,MySQL,Postgresql,Oracle等),这篇文章主要介绍了SQLAlchemy的主要组件有哪些,本文给大家介绍的非常详细,对大家的学习具有一定的参考借鉴价值,需要的朋友可以参考
    2023-08-08
  • python实现阶乘的三种方法

    python实现阶乘的三种方法

    阶乘是基斯顿·卡曼于 1808 年发明的运算符号,是数学术语,一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1,本文给大家介绍了python实现阶乘的三种方法,通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • Python实现投影法分割图像示例(一)

    Python实现投影法分割图像示例(一)

    今天小编就为大家分享一篇Python实现投影法分割图像示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01

最新评论