多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库。而多线程 thread 在 Python 里面被称作鸡肋的存在!
那么是不是python的多线程就完全没用了呢?
在这里我们进行分类讨论:
1、CPU密集型代码(各种循环处理、计数等等),在这种情况下,由于计算工作多,ticks计数很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),所以python下的多线程对CPU密集型代码并不友好。
2、IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。所以python的多线程对IO密集型代码比较友好。
多线程爬取知乎美女图片的例子:
# -*- coding: utf-8 -*- """ Created on Mon Apr 23 20:33:52 2018 多线程爬取知乎图片练习 @author: 51207 """ import time from selenium import webdriver driver=webdriver.Chrome() driver.get("https://www.zhihu.com/question/66313867") time.sleep(5) n=0 a=0 while n<50: js="var q=document.documentElement.scrollTop=%s"%(a+3000) driver.execute_script(js) time.sleep(1) a=a+3000 n=n+1 html = driver.execute_script("return document.documentElement.outerHTML") #driver.close() import re from urllib import request from bs4 import BeautifulSoup soup=BeautifulSoup(html,'lxml') links=re.findall('http.{5,60}hd\.jpg',str(soup)) links=list(set(links)) path = r'D:\mywork\python\pachong\images' #路径前的r是保持字符串原始值的意思,就是说不对其中的符号进行转义 import threading import queue SHARE_Q=queue.Queue() #构造一个不限制大小的队列 _WORKER_THREAD_NUM=4 #设置线程个数 class MyThread(threading.Thread): def __init__(self,func): super(MyThread,self).__init__() self.func= func def run(self): self.func() def do_something(item): print(item) try: request.urlretrieve(item,path+'\%s.jpg' % time.time()) except: print('can"t download') def worker(): global SHARE_Q while not SHARE_Q.empty(): item= SHARE_Q.get() #获得任务 do_something(item) time.sleep(1) SHARE_Q.task_done() def main(): global SHARE_Q threads=[] for link in links: #向队列中放入任务 SHARE_Q.put(link) #开启多个线程 for i in range(_WORKER_THREAD_NUM): print(i) thread=MyThread(worker) thread.start() threads.append(thread) for thread in threads: thread.join() #等待所有任务完成 SHARE_Q.join() if __name__=='__main__': main()