线程:是任务的执行者。
进程:是一个动态的概念。
适用情况:
IO密集用多线程。
CPU密集用多进程。
原因:Cpython解释器中使用了GIL全局解释锁,一个进程只有一个锁。只有拿到这个锁的线程才能获取解释器,取解释执行代码。这就导致了即使开了多线程,实际上只有一个线程在执行。
因此当进行CPU计算密集的任务时候。即使开了多线程也没用。故而需要实现多进程,这样才能保证几个计算是同时执行的。
线程池:
线程的创建和销毁都需要消耗资源。为了避免频繁的创建销毁线程造成资源浪费。提出了多线程的概念。
线程池实际上就是规定了一个最大线程数,同时实现了任务队列。
当一个任务到来的时候,如果有空线程,则将任务分配给该线程。
如果没有空线程,则检查当前存在的线程数是否<最大线程数。
如果小于,则创建线程,分配任务。
如果已经达到了最大线程数,那么不好意思,您去任务队列里排队等着线程空出来。
线程池的一些缺点包括:
需要合理配置:线程池的性能和效果受到配置参数的影响,需要根据具体的应用场景和硬件环境来合理配置线程池的大小、任务队列的大小等参数。
可能引发资源泄露:如果线程池中的线程长时间闲置而不被使用,可能会导致资源的浪费和泄露。
可能引发死锁:在使用线程池时,如果任务之间存在依赖关系,可能会引发死锁问题,需要额外的注意和处理。
代码:
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
def task(n):
"""模拟一个耗时任务"""
print(f"Task {n} started at {time.strftime('%H:%M:%S', time.localtime())}")
time.sleep(n)
print(f"Task {n} finished at {time.strftime('%H:%M:%S', time.localtime())}")
return n * n
def main():
# 定义任务列表
tasks = [1, 2, 3, 4, 5]
# 创建一个线程池,最多同时运行5个线程
with ThreadPoolExecutor(max_workers=5) as executor:
# 提交任务到线程池
futures = {executor.submit(task, n): n for n in tasks}
# 处理已完成的任务
for future in as_completed(futures):
n = futures[future]
try:
result = future.result()
print(f"Task {n} returned: {result}")
except Exception as e:
print(f"Task {n} generated an exception: {e}")
if __name__ == "__main__":
main()
标签:__,Task,python,任务,线程,time,多线程
From: https://www.cnblogs.com/jiyuebo/p/18438535