线程池和进程池
(1)简介
- 在 Python 中,线程池(ThreadPoolExecutor)和进程池(ProcessPoolExecutor)是用于并发执行任务的两种机制。它们都可以有效地管理并发执行的任务,并且能够自动管理线程或进程的生命周期,从而简化了并发编程。
(1)线程池
-
基于线程的并发:线程池利用了线程的并发执行来加速任务的完成。Python 中的线程池通常使用标准库中的 concurrent.futures 模块来实现。
-
适用于 I/O 密集型任务:线程池适用于那些主要受限于 I/O 操作而不是 CPU 计算的任务,因为 Python 的全局解释器锁(GIL)会限制多线程情况下的并行计算。
-
示例代码:
import time from concurrent.futures import ThreadPoolExecutor def run(i): print(f'这是参数{i} 开始') time.sleep(1) print(f'这是参数{i} 结束') def main_thread(): pool = ThreadPoolExecutor(5) for i in range(1,10): pool.submit(run, i) if __name__ == '__main__': main_thread()
(2)进程池
-
基于进程的并发:进程池使用多个进程来并行执行任务。每个进程都有自己的 Python 解释器和独立的内存空间,因此可以避免 GIL 的限制。
-
适用于 CPU 密集型任务:进程池适用于需要大量 CPU 计算的任务,因为它们可以充分利用多核 CPU 的优势。
-
示例代码:
import time from concurrent.futures import ProcessPoolExecutor def run(i): print(f'这是参数{i} 开始') time.sleep(1) print(f'这是参数{i} 结束') def main_process(): pool = ProcessPoolExecutor(5) for i in range(1,10): pool.submit(run, i) if __name__ == '__main__': main_process()
总的来说,如果任务主要是 I/O 密集型的,那么线程池通常是更好的选择,而如果任务主要是 CPU 密集型的,那么进程池可能更适合。在实际应用中,可以根据任务的性质和系统资源进行选择。
(2)返回值
- res = pool. Submit(run, i)
- print(f'这是pool 的返回值 {res.result()}')
import time
from concurrent.futures import ProcessPoolExecutor
def run(i):
print(f'这是参数{i} 开始')
time.sleep(1)
print(f'这是参数{i} 结束')
return i**2
def main_process():
pool = ProcessPoolExecutor(5)
for i in range(1,10):
res = pool.submit(run, i)
print(f'这是pool 的返回值 {res.result()}')
if __name__ == '__main__':
main_process()
(3)shutdown()
- 等待所有子进程结束,拿到结果
import time
from concurrent.futures import ProcessPoolExecutor
def run(i):
print(f'这是参数{i} 开始')
time.sleep(1)
print(f'这是参数{i} 结束')
return i**2
def main_process():
res_list = []
pool = ProcessPoolExecutor(5)
for i in range(1,10):
res = pool.submit(run, i)
res_list.append(res)
pool.shutdown()
for res in res_list:
print(f'这是pool 的返回值 {res.result()}')
if __name__ == '__main__':
main_process()
(4)异步回调函数
-
异步回调函数是一种编程模式,常用于处理异步操作完成后的结果。在异步编程中,某些操作可能需要花费一定的时间来完成,但是我们不希望在等待这些操作完成时阻塞程序的执行,因此我们会将这些操作放在后台执行,并在其完成后通知主程序。
-
异步回调函数通常用于以下情况:
-
异步 I/O 操作:例如网络请求、文件读写等,这些操作可能需要花费较长时间,我们不希望在等待它们完成时阻塞程序的执行。
-
事件处理:例如 GUI 应用程序中的事件响应,当用户触发某些事件时,我们可能需要执行一些操作,并在操作完成后通知用户或更新界面。
- 异步回调函数的工作流程通常是这样的:
-
我们定义一个异步操作,例如一个函数,它可能会异步执行某些耗时的任务,并在任务完成后调用一个回调函数。
-
在调用异步操作时,我们通常会提供一个回调函数作为参数,以便在操作完成后被调用。
-
异步操作在后台执行,不会阻塞程序的执行。当操作完成后,会自动调用提供的回调函数,并将结果传递给它。
- 异步回调函数有助于编写高效的异步程序,使得程序能够更好地利用资源,并提高响应速度。在 Python 中,异步编程可以使用
asyncio
、concurrent.futures
等模块来实现。
from concurrent.futures import ThreadPoolExecutor
def task(n):
# 模拟一个耗时的任务
result = n * n
return result
def callback(future):
# 回调函数,在任务完成时被调用
print("任务完成,结果为:", future.result())
def main():
# 创建线程池
t = ThreadPoolExecutor(3)
# 提交任务并设置回调函数
future1 = t.submit(task, 5)
future1.add_done_callback(callback)
future2 = t.submit(task, 10)
future2.add_done_callback(callback)
future3 = t.submit(task, 15)
future3.add_done_callback(callback)
# 手动关闭线程池
t.shutdown()
if __name__ == "__main__":
main()
标签:__,异步,print,线程,进程,main,pool
From: https://www.cnblogs.com/ssrheart/p/18015830