七.多线程
1.多线程
概念:让程序能够同时执行多个任务
主线程:main是主线程
子线程:自己创建的线程
两个线程一起在运行
(1)导入库
from threading import Thread
(2)创建任务
def func():
(3)创建线程
t = Thread(target=func,args(任务参数))
(4)启动线程
t.start()
2.线程池
线程池就是储存线程的地方,可以自动的对线程进行管理(包括开辟线程,销毁线程,回收等等),始终保持线程池中有我们需要数量的线程。
(1)导入库
from concurrent.futures import ThreadPoolExecutor
(2)创建线程池
if __name__ == '__main__':
#创建线程池(线程池中有20个线程)
with ThreadPoolExecutor(20) as t:
(3)创建任务
def func2(name):
for i in range(100):
print(name,i)
(4)提交任务
if __name__ == '__main__':
#创建线程池(线程池中有20个线程)
with ThreadPoolExecutor(20) as t:
#10个任务,把任务提交给线程池,线程池进行自己分配
t.submit(func2,"zhou")
t.submit(func2, "li")
t.submit(func2, "wang")
t.submit(func2, "zhang")
t.submit(func2, "yang")
t.submit(func2, "qi")
t.submit(func2, "rong")
t.submit(func2, "fu")
t.submit(func2, "chen")
t.submit(func2, "cuan")
3.练习
利用线程池下载图片,对于昨天练习的扩充。
import requests
import re
import json
from concurrent.futures import ThreadPoolExecutor
#线程池任务
def download(imgsrc):
name = imgsrc.split("/")[-1]
print("开始下载:%s"%name)
#发送网络请求
resp_img = requests.get(imgsrc)
#此时拿不到resp.text,利用resp.content拿到的是字节
with open(f"picture/{name}",mode="wb") as f:
f.write(resp_img.content)
def main():
url = "https://desk.zol.com.cn/bizhi/9374_114228_2.html"
resp = requests.get(url)
resp.encoding="gbk"
#print(resp.text)
#从正则.*?提取的内容一定是字符串
obj = re.compile(r"var deskPicArr.*?=(?P<deskPicArr>.*?);",re.S)
result = obj.search(resp.text)
deskPicStr = result.group("deskPicArr")
#把类似字典的字符串变成字典——使用json
deskPic = json.loads(deskPicStr)
#开辟线程池
with ThreadPoolExecutor(10) as t:
for item in deskPic['list']:
oriSize = item.get("oriSize")
imgsrc = item.get("imgsrc")
imgsrc = imgsrc.replace("##SIZE##",oriSize)
t.submit(download,imgsrc)
print("下载完成!")
if __name__ == '__main__':
main()