首页 > 系统相关 >线程池和进程池

线程池和进程池

时间:2024-02-14 23:25:46浏览次数:27  
标签:__ 异步 print 线程 进程 main pool

线程池和进程池

(1)简介

  • 在 Python 中,线程池(ThreadPoolExecutor)和进程池(ProcessPoolExecutor)是用于并发执行任务的两种机制。它们都可以有效地管理并发执行的任务,并且能够自动管理线程或进程的生命周期,从而简化了并发编程。

(1)线程池

  1. 基于线程的并发:线程池利用了线程的并发执行来加速任务的完成。Python 中的线程池通常使用标准库中的 concurrent.futures 模块来实现。

  2. 适用于 I/O 密集型任务:线程池适用于那些主要受限于 I/O 操作而不是 CPU 计算的任务,因为 Python 的全局解释器锁(GIL)会限制多线程情况下的并行计算。

  3. 示例代码

    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)进程池

  1. 基于进程的并发:进程池使用多个进程来并行执行任务。每个进程都有自己的 Python 解释器和独立的内存空间,因此可以避免 GIL 的限制。

  2. 适用于 CPU 密集型任务:进程池适用于需要大量 CPU 计算的任务,因为它们可以充分利用多核 CPU 的优势。

  3. 示例代码

    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)异步回调函数

  • 异步回调函数是一种编程模式,常用于处理异步操作完成后的结果。在异步编程中,某些操作可能需要花费一定的时间来完成,但是我们不希望在等待这些操作完成时阻塞程序的执行,因此我们会将这些操作放在后台执行,并在其完成后通知主程序。

  • 异步回调函数通常用于以下情况:

  1. 异步 I/O 操作:例如网络请求、文件读写等,这些操作可能需要花费较长时间,我们不希望在等待它们完成时阻塞程序的执行。

  2. 事件处理:例如 GUI 应用程序中的事件响应,当用户触发某些事件时,我们可能需要执行一些操作,并在操作完成后通知用户或更新界面。

  • 异步回调函数的工作流程通常是这样的:
  1. 我们定义一个异步操作,例如一个函数,它可能会异步执行某些耗时的任务,并在任务完成后调用一个回调函数。

  2. 在调用异步操作时,我们通常会提供一个回调函数作为参数,以便在操作完成后被调用。

  3. 异步操作在后台执行,不会阻塞程序的执行。当操作完成后,会自动调用提供的回调函数,并将结果传递给它。

  • 异步回调函数有助于编写高效的异步程序,使得程序能够更好地利用资源,并提高响应速度。在 Python 中,异步编程可以使用 asyncioconcurrent.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

相关文章

  • C++多线程 第五章 C++内存模型和原子类型
    第五章C++内存模型和原子类型无论其他语言如何,C++是一门系统编程语言.委员会希望不再需要一个比C++低级的语言.内存模型基础C++程序中所有的数据均是由对象(object)组成的.C++标准定义对象为"存储区域",经管它会为这些对象分配属于它们的类型和生存期.无论什么类型,对象......
  • 线程池工作流程 工厂流水线打比方
    线程池工作原理关于线程池的工作原理,我用下面的7幅图来展示。1.通过execute方法提交任务时,当线程池中的线程数小于corePoolSize时,新提交的任务将通过创建一个新线程来执行,即使此时线程池中存在空闲线程。2.通过execute方法提交任务时,当线程池中线程数量达到corePoolSize时,新......
  • day17_进程管理
    linux资源管理篇昨日内容回顾1.先看状态,再去启动systemctlstatusfirewalldsystemctlrestartfirewalldsystemctllist-unit-files|grepfirewalld1.先理解服务的意思,服务,就是你安装的软件名字2.服务就是一个软件程序,会提供可用的命令,去操控这个软件3.firewall......
  • 线程池工作原理和实现原理
     为什么要使用线程池不使用线程池会怎么样?当需要多线程并发执行任务时,只能不断的通过newThread创建线程,每创建一个线程都需要在堆上分配内存空间,同时需要分配虚拟机栈、本地方法栈、程序计数器等线程私有的内存空间,当这个线程对象被可达性分析算法标记为不可用时被GC回收,这样......
  • 为什么要有线程?
    这是我学习时一直想不通的问题。尽管很多书籍和视频都做了解释,但由于没有实际的案例和场景,导致我不能真正明白这个问题。接下来说下我的迷思,以及迷思的答案。线程可以有效配合多核处理器,提高效率。这个是最广泛的说法,对于网络服务器,对于每个请求创建一个线程,可以CPU同时处理多个......
  • 【c&c++】linux守护进程设置开机自启动的两种方式
    linux守护进程设置开机自启动的两种方式前期准备第一种方式第二种方式 前期准备首先,我们创建一个守护进程1、守护进程初始化程序init.c文件如下:#include<unistd.h>#include<signal.h>#include<sys/param.h>#include<sys/types.h>#include<sys/stat.h>voidinit......
  • C#中获取进程当前路径各种方法的测试
    C#中获取进程当前路径各种方法的测试在CSharp中,获取当前进程的路径有很多种方式。同一个api在不同的运行和发布方式中,又会产生不同的效果。下面我用代码来测试一下效果,运行环境是:Windows10,.Net8。测试程序为放在``D:\的CurrentPathTest`目录。//不同的发布及运行方式//1.......
  • 如何利用内核跟踪点排查短时进程问题?
    在排查系统CPU使用率高的问题时,很可能遇到过这样的困惑:明明通过 top 命令发现系统的CPU使用率(特别是用户CPU使用率)特别高,但通过 ps、pidstat 等工具都找不出CPU使用率高的进程。这是什么原因导致的呢?一般情况下,这类问题很可能是以下两个原因导致的:第一,应用程序里面......
  • C++多线程 第四章 同步并发操作
    第四章同步并发操作等待事件设想一个情景:你正坐在一辆从哈尔滨驶向郴州的绿皮火车上,这趟车需要耗时2天2夜,合计3000公里的路程.于是在这里,我们将你和司机视作为两个线程.你的任务是在目的地下车,司机的任务是将车开到目的地.假设你和司机坐在同一个车厢内,并且你是个不说......
  • 【多线程例题】使用三个线程,分别可以打印A,B,C。要求实现三个线程协同打印,顺序打印出ABC
    顺序打印-进阶版方法一:三个线程竞争同一个锁,通过count判断是否打印三个线程分别打印A,B,C方法一:通过count计数打印(三个线程上同样的锁,打印一个,召唤所有锁,如果不满足条件,则wait等待,锁自动解锁)方法二:/***有三个线程,分别只能打印A,B和C*要求按顺序打印ABC,打印10次*输出示......