一、进程和线程的概念(一句话概述)
进程:我们运行的程序通常会对应一个或多个进程,进程是操作系统分配内存的基本单位。
线程:一个进程通常会包含一个或多个线程,线程是操作系统分配CPU的基本单位。
单线程程序--->我们的程序中只有一个执行线索(主线程)--->创建多个线程(有多个可以并发的部分)
技术交流群:830709780
注:一个程序至少有一个进程,一个进程至少有一个线程(主线程),进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
二、进程和线程的区别
1.操作系统资源管理方式是不一样的,进程有独立的地址空间,进程崩溃后会有保护模式让其不会对其他的进程产生影响。而线程则不然,线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,所以一个线程挂掉可能影响整个进程挂掉。
2.进程的并发性没有线程高。
3.每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中。由应用程序提供多个线程执行控制。
4.对于应用程序来说,多线程是可以同时有多个执行部分同时执行。但对于操作系统来说是没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配
注:多线程容易调度,有效地实现并发性。对内存的开销比较小。创建线程比创建进程要快。
三、线程池的概念
在编写多线程程序时,一定要注意线程的创建和释放有较大的开销,而且如果创建了太多的线程,线程之间的调度切换本身也是有开销的,所以线程并不是越多越好,最好的用法时创建若干线程,然后重复的使用他们。
线程池:先用一个容器,提前创建好若干个线程放进去,用线程的时候从线程池中借出一个线程,用完之后,不要释放线程,而是把这个线程放回池子,让线程可以被重复利用。
注:池化技术基本上都是空间换时间。
四、代码演示(调用第三方接口下载(多线程和线程池)图片)
# coding=utf8
# @time:2022/5/19 17:02
import time
from concurrent.futures import ThreadPoolExecutor
import requests
def down_picture(picture_url):
resp = requests.get(picture_url)
if resp.status_code == 200:
filename = picture_url[picture_url.rfind('/'):]
with open(f'images/{filename}', 'wb') as f:
f.write(resp.content)
def read_picture():
futures = []
with ThreadPoolExecutor(max_workers=10) as pool: # 线程池,最大进程10
# threads = []
star = time.time()
format = 'png'
header = {
'User-Agent': 'Mozilla/5.0 (compatible; U; ABrowse 0.6; Syllable) AppleWebKit/420+ (KHTML, like Gecko)'}
data = {'key': '919928ff6d14cXXXXXXXXXXXXXX', 'url': 'https://www.hXXXXXXXXXXXXXX.com'} # 参数根据实际情况填写
for page in range(1, 6):
resp = requests.get('http://api.xxxxxxx.com', params=data, headers=header) # 参数根据实际情况填写
picture_list = resp.json()['newslist']
# print(picture_list)
for picture in picture_list:
picture_url = picture['picUrl']
# print(picture_url)
# down_picture(picture_url)
#线程池
f = pool.submit(down_picture, picture_url)
'''''''''
# 普通的多线程方法
thd = threading.Thread(target=down_picture,args=(picture_url,))
threads.append(thd)
thd.start()
# print(threads)
# 等待刚才启动的子线程所有执行时间
for t in threads:
t.join()
'''''''''
for f in futures:
f.result()
end = time.time()
print(end - star) # 4.877447128295898
if __name__ == '__main__':
read_picture()
下载情况示:
更多安全分享,请关注【安全info】微信公众号!