Python基础语法文章导航:
- Python基础(01初识数据类型&变量)
- Python基础(02条件&循环语句)
- Python基础(03字符串格式化&运算符&进制&编码)
- Python基础(04 基础练习题)
- Python数据类型(day05整型&布尔类型&字符串类型)
- Python数据类型(06列表&元组)
- Python数据类型(07集合&字典&浮点型&None)
- Python文件操作01(自动化测试文件相关操作)
-
Python函数入门(08函数定义&参数&返回值)
-
Python文件操作02(自动化测试文件相关操作)
-
Python函数(10生成器&内置函数&推导式)
-
Python函数(11自定义模块&第三方模块&内置模块)
-
Python函数(12时间处理&正则表达式)
-
Python函数(13面向对象)
-
Python面向对象(15成员&成员修饰符)
目录
一.了解进程和线程
二.多线程
三.多进程
四.GIL锁
一.了解进程和线程
先来了解下进程和线程。
类比:
-
一个工厂,至少有一个车间,一个车间中至少有一个工人,最终是工人在工作。
-
一个程序,至少有一个进程,一个进程中至少有一个线程,最终是线程在工作。
线程,是计算机中可以被cpu调度的最小单元(真正在工作)。
进程,是计算机资源分配的最小单元(进程为线程提供资源)。一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源。
二.多线程
基于多线程对上述串行示例进行优化:
-
一个工厂,创建一个车间,这个车间中创建 3个工人,并行处理任务。
-
san一个程序,创建一个进程,这个进程中创建 3个线程,并行处理任务。
import time
import requests
url_list = [
("东北F4模仿秀.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"),
("卡特扣篮.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"),
("罗斯mvp.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
]
for file_name, url in url_list:
res = requests.get(url)
with open(file_name, mode='wb') as f:
f.write(res.content)
import time
import requests
import threading
"""
def func(a1,a2,a3):
pass
t = threaing.Thread(target=func,args=(11,22,33))
t.start()
"""
url_list = [
("东北F4模仿秀.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"),
("卡特扣篮.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"),
("罗斯mvp.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
]
def task(file_name, video_url):
res = requests.get(video_url)
with open(file_name, mode='wb') as f:
f.write(res.content)
print(time.time())
for name, url in url_list:
# 创建线程,让每个线程都去执行task函数(参数不同)
t = threading.Thread(target=task, args=(name, url))
t.start()
三.多进程
基于多进程对上述串行示例进行优化:
-
一个工厂,创建 三个车间,每个车间 一个工人(共3人),并行处理任务。
-
一个程序,创建 三个进程,每个进程 一个线程(共3人),并行处理任务。
import time
import requests
import multiprocessing
# 进程创建之后,在进程中还会创建一个线程。
# t = multiprocessing.Process(target=函数名, args=(name, url))
# t.start()
url_list = [
("东北F4模仿秀.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"),
("卡特扣篮.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"),
("罗斯mvp.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
]
def task(file_name, video_url):
res = requests.get(video_url)
with open(file_name, mode='wb') as f:
f.write(res.content)
print(time.time())
if __name__ == '__main__':
print(time.time())
for name, url in url_list:
t = multiprocessing.Process(target=task, args=(name, url))
t.start()
四.GIL锁
GIL, 全局解释器锁(Global Interpreter Lock),是CPython解释器特有一个玩意,让一个进程中同一个时刻只能有一个线程可以被CPU调用。
如果程序想利用 计算机的多核优势,让CPU同时处理一些任务,适合用多进程开发(即使资源开销大)。
如果程序不利用 计算机的多核优势,适合用多线程开发。
常见的程序开发中,计算操作需要使用CPU多核优势,IO操作不需要利用CPU的多核优势,所以,就有这一句话:
-
计算密集型,用多进程,例如:大量的数据计算【累加计算示例】。
-
IO密集型,用多线程,例如:文件读写、网络数据传输【下载抖音视频示例】。
累加计算示例(计算密集型):
-
串行处理
import time
start = time.time()
result = 0
for i in range(100000000):
result += i
print(result)
end = time.time()
print("耗时:", end - start) # 耗时: 9.522780179977417
多进程处理
import time
import multiprocessing
def task(start, end, queue):
result = 0
for i in range(start, end):
result += i
queue.put(result)
if __name__ == '__main__':
queue = multiprocessing.Queue()
start_time = time.time()
p1 = multiprocessing.Process(target=task, args=(0, 50000000, queue))
p1.start()
p2 = multiprocessing.Process(target=task, args=(50000000, 100000000, queue))
p2.start()
v1 = queue.get(block=True) #阻塞
v2 = queue.get(block=True) #阻塞
print(v1 + v2)
end_time = time.time()
print("耗时:", end_time - start_time) # 耗时: 2.6232550144195557
当然,在程序开发中 多线程 和 多进程 是可以结合使用,例如:创建2个进程(建议与CPU个数相同),每个进程中创建3个线程。
import multiprocessing
import threading
def thread_task():
pass
def task(start, end):
t1 = threading.Thread(target=thread_task)
t1.start()
t2 = threading.Thread(target=thread_task)
t2.start()
t3 = threading.Thread(target=thread_task)
t3.start()
if __name__ == '__main__':
p1 = multiprocessing.Process(target=task, args=(0, 50000000))
p1.start()
p2 = multiprocessing.Process(target=task, args=(50000000, 100000000))
p2.start()