首页 > 编程 > Python > 正文

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

2020-01-04 17:42:21
字体:
来源:转载
供稿:网友
Python由于有全锁局的存在,并不能利用多核优势。所以,如果你的多线程进程是CPU密集型的,那多线程并不能带来效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。
 

目的:

是学习python 多线程的工作原理,及通过抓取400张图片这种IO密集型应用来查看多线程效率对比

import requestsimport urlparseimport osimport timeimport threadingimport Queuepath = '/home/lidongwei/scrapy/owan_img_urls.txt'#path = '/home/lidongwei/scrapy/cc.txt'fetch_img_save_path = '/home/lidongwei/scrapy/owan_imgs/'# 读取保存再文件里面400个urlswith 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.4431338313线程 Done 12.9201757908 2线程 Done 32.86282992361线程 Done 54.6115460396 

总结

Python 自带GIL 大锁, 没有真正意义上的多线程并行执行。GIL 大锁会在线程阻塞的时候释放,此时等待的线程就可以激活工作,这样如此类推,大大提高IO阻塞型应用的效率。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表