Python的併發
Python中由於存在GIL的問題,所以其在多線程上無法充分發揮多核的優勢和威力,一般都會推薦使用多進程的方式來發揮多核的效率。
除了多進程的方式之外,還可以使用coroutine協程的方式來提升併發的處理效率。
進程、線程和協程
參考文章: https://www.cnblogs.com/zhaof/p/7536569.html
這篇文章關於進程、線程和協程之間的異同已經做了非常好的闡述,這裏就不再單獨展開篇幅分析和討論了。
併發模式
目前併發模式應該是應用單線程的協程處理模式。多進程開啓,進程中使用單線程模式,在線程中使用協程的方式。
代碼示例
協程方式,下載圖片
from bs4 import BeautifulSoup
import requests
from gevent import monkey; monkey.patch_all()
import gevent
from urllib.parse import urlparse
import shutil
import os
url = 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fr=&sf=1&fmq=1526269427171_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E5%A3%81%E7%BA%B8'
r = requests.get(url)
html = r.text
soup = BeautifulSoup(html, 'lxml')
links = soup.find_all('img')
print(links)
images = [i.get("src") for i in links if i.get("src") and len(i.get("src"))>0]
print("Len:" + str(len(images)))
def download_image(url):
print("image:" + url)
file_name = os.path.basename(url)
response = requests.get(url, stream=True)
with open(file_name, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
tasks = []
for image in images:
tasks.append(gevent.spawn(download_image, "http:" + image))
gevent.joinall(tasks)
運行結果: