網(wǎng)站大屏輪播圖效果怎么做公眾號排名優(yōu)化軟件
免責聲明:本文僅做技術交流與學習...?
目錄
了解進程和線程
單個線程(主線程)在執(zhí)行
多線程
線程池
協(xié)程(爬蟲多用)
假異步:(同步)
真異步:
爬蟲代碼模版
異步-爬蟲
同步效果--19+秒
異步效果--7+秒
了解進程和線程
? # --------------------> # ------> # ? ? ? -------> # ? ? ? ? ? ? ? --------> ? # 1-線程 #線程:執(zhí)行一個軟件后的操作---點贊,簽到,評論等等 #進程:執(zhí)行一個軟件 ? ?
一家公司里面人去做事. 1人,2人,多人... (要合理分配,合理運用.) --30萬的資本,養(yǎng)不起10000人呀. ? 1個進程必須要有一個線程,--- 線程不是越多越好. 單線程/多線程 ? ? 進程:資源單元 線程:執(zhí)行單元 ? ? ? ?
# 每一個py程序默認都有一個線程的, print("111") ?
單個線程(主線程)在執(zhí)行
多線程
from threading import Thread # alt + enter 快捷鍵導包 ? def func(name):for i in range(1, 1000):print("func函數(shù)在執(zhí)行---" + str(i),name) ? ? # func() # 這樣寫就是主線程執(zhí)行. ? # 創(chuàng)建線程對象,分配線程的任務是func ? (公司招人要分配任務) t = Thread(target=func,args=('my name xiaodi',)) ? # args的參數(shù)必須是一個元組. # 啟動線程: ? ? ? ? ? ? ? ? ? ? ? (員工先忙完手頭工作,然后真正工作) t.start() ? # 線程的狀態(tài),可以開始工作的狀態(tài)了,具體的執(zhí)行時間由CPU決定. ? t1 = Thread(target=func,args=('xiaosedi',)) t1.start() ? # 主線程不會受到子線程(其他線程)的干擾. 主線程該干什么就干什么. for i in range(1, 1000):print("主---" + str(i)) # 多個線程都輸出到控制臺上,就會亂. ? # 傳參在創(chuàng)建線程對象時也要傳. ? # 線程數(shù)由電腦的CPU決定,如果處理不好,反而會效率下降. ?
線程池
# 線程池 :一次性開辟一些線程,直接給線程池提交任務,具體的任務到底哪個線程執(zhí)行,是由線程池分配的 from concurrent.futures.thread import ThreadPoolExecutor ? ? def func(name):for i in range(1000):print(name, 'func函數(shù)執(zhí)行', i) ? ? # 創(chuàng)建一個有50個線程的線程池.(合理的利用資源~) # -----執(zhí)行10次func函數(shù),每個func函數(shù)執(zhí)行1000次. with ThreadPoolExecutor(50) as t:# ? ? t = ThreadPoolExecutor(50)for i in range(10):# 給線程去提交任務t.submit(func, name=f'線程{i}') ? # 等待線程池中的任務全部執(zhí)行完畢,才會繼續(xù)執(zhí)行 print('print執(zhí)行了')
協(xié)程(爬蟲多用)
import asyncio import time ? def func():print("函數(shù)開始")time.sleep(3) ? # 當?shù)酱藭r,當前線程為阻塞狀態(tài),CPU不會為當前程序提供工作.print("函數(shù)結束") func() ? # 阻塞代碼:(必須要等待某個結果等等 # input(等待輸入) ? time.sleep(強制等待) ? requests(請求網(wǎng)絡,client<->server有時間差, # 程序基于 i(input) o(output) 操作時,線程機會處于阻塞狀態(tài),CPU就不會提供工作. # ---阻塞的時候就會干等著,---怎么讓CPU在干等著的時候也做點事情呢?--->協(xié)程!!! ? # 協(xié)程:當程序遇見了io操作的時候,可以選擇性的切換到其它任務上。 # 多任務異步操作:
假異步:(同步)
import asyncio import time ? ? async def func1():print('func1函數(shù)開始')time.sleep(3) ?# 屬于同步操作代碼。# 只要在異步程序中出現(xiàn)了同步操作,異步就被中斷# await asyncio.sleep(3)print('func1函數(shù)結束') ? ? async def func2():print('func2函數(shù)開始')time.sleep(2)# await asyncio.sleep(2)print('func2函數(shù)結束') ? ? async def func3():print('func3函數(shù)開始')time.sleep(4)# await asyncio.sleep(4)print('func3函數(shù)結束') ? ? # 拿到函數(shù)的對象 f1 = func1() f2 = func2() f3 = func3() tasks = [# 創(chuàng)建一個任務f1, f2, f3 ] start = time.time() # 如果是多個任務,需要一個asyncio.wait(任務列表)搭配 asyncio.run(asyncio.wait(tasks)) print(time.time() - start) ?
9+秒結束!!! ---沒有異步呀---
因為time是一個同步模塊,
time.sleep() # 屬于同步操作代碼。 # 只要在異步程序中出現(xiàn)了同步操作,異步就被中斷
真異步:
import asyncio import time ? ? async def func1():print('func1函數(shù)開始')# time.sleep(3) ? ? ? ? # 屬于同步操作代碼await asyncio.sleep(3) ?# 異步休眠代碼 ? ? ? --不是強制性的休眠,而是掛起,讓他先去忙別的東西,等好了再回來.print('func1函數(shù)結束') ? ? async def func2():print('func2函數(shù)開始')# time.sleep(2)await asyncio.sleep(2)print('func2函數(shù)結束') ? ? async def func3():print('func3函數(shù)開始')# time.sleep(4)await asyncio.sleep(4)print('func3函數(shù)結束')#async def main(): # ? ? f1 = func1() # ? ? f2 = func2() # ? ? f3 = func3() # ? ? tasks = [ # ? ? ? ? f1,f2,f3 # ? ? ? ? # 創(chuàng)建一個任務 # ? ? ? ? # asyncio.create_task(func1()), # ? ? ? ? # asyncio.create_task(func2()), # ? ? ? ? # asyncio.create_task(func3()) # ? ? ] # ? ? await asyncio.wait(tasks) # start = time.time() # asyncio.run(main()) # print(time.time() - start) ? f1 = func1() f2 = func2() f3 = func3() tasks = [f1, f2, f3# 創(chuàng)建一個任務 ] ? start = time.time() # 如果是多個任務,需要一個asyncio.wait(任務列表)搭配 asyncio.run(asyncio.wait(tasks)) print(time.time() - start)
4+秒 , 好快呀...
爬蟲代碼模版
import asyncio ? ? async def download(url):print('準備開始下載')# await asyncio.sleep(2) # 網(wǎng)絡請求# requests.get(url) ? ? # 異步效果中斷,那怎么結合呢???print('下載完成') ? ? async def main():urls = ['地址1','地址2','地址3',]# tasks = []# for url in urls:# ? tasks.append(download(url)) ?# 列表推導式寫法 循環(huán)url列表,每循環(huán)一次,創(chuàng)建一個任務tasks = [download(url) for url in urls]await asyncio.wait(tasks) ? ? asyncio.run(main()) ?
requests.get(url) # 異步效果中斷,那怎么結合呢???
只要出現(xiàn)同步操作,異步就會被終斷.
-------->
異步-爬蟲
因為requests模塊是同步的,如果在異步協(xié)程中編寫同步代碼,異步效果沒有。 ? 如何解決? 更換支持異步的請求模塊 aiohttp == requests pip install aiohttp pip install aiofiles
同步效果--19+秒
import time import requests ? urls = ['https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_christian_dimitrov_02_1920x1080.jpg','https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_pablo_carpio_17_1920x1080.jpg','https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_dejian_wu_04_1920x1080.jpg' ] t = time.time() for url in urls:res = requests.get(url).content# 文件名name = url.split('/')[-1]with open(name, 'wb') as f:f.write(res) print(f'requests花費時間===》{time.time() - t}') # requests花費時間===》19.635247230529785
異步效果--7+秒
import asyncio import time import aiofiles import aiohttp urls = ['https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_christian_dimitrov_02_1920x1080.jpg','https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_pablo_carpio_17_1920x1080.jpg','https://www.cgwallpapers.com/wallpapers_free_wreoiux/wallpaper_dejian_wu_04_1920x1080.jpg' ] async def download(url):print('準備開始下載--->')# s = aiohttp.ClientSession() == requests ? ? ? ? ? ? #拿到對象# s.get() s.post === requests.get() requests.post()# --------------------------------------# aiohttp ? ? ? ? ? ? ? ? ? requests# res.text() ? ? ? ? ? ? ? ? res.text# res.read() ? ? ? ? ? ? ? ? res.content# res.json() ? ? ? ? ? ? ? ? res.json()# --------------------------------------async with aiohttp.ClientSession() as s:async with s.get(url) as res:# 寫入文件name = url.split('/')[-1]# 文件正常操作:# with open(name,'wb')as f:# ? ? f.write(await res.read())# 文件異步操作:async with aiofiles.open(name, 'wb') as f:await f.write(await res.read())print('下載完成') async def main(urls):tasks = [download(url) for url in urls]await asyncio.wait(tasks) t = time.time() asyncio.run(main(urls)) print(f'aiohttp花費時間===》{time.time() - t}') # aiohttp花費時間===》7.244250774383545 ?