【Python】多进程线程与CPU核数

  • 多进程数量设置为CPU核数,或者略小于CPU核数;
  • 多线程数量,如果是CPU密集任务设为1;如果是IO密集设为合理的值;
  • IO密集型:系统运作,大部分的状况是CPU 在等I/O (硬盘/内存)的读/写。
  • 计算密集型:大部份时间用来做计算、逻辑判断等CPU 动作的程序称之CPU 密集型。
  • 对于IO密集型,多线程效率高于多进程;
  • 对于计算密集型任务,多进程效率高于多线程。

总结一下

IO密集网络请求,文件读写多进程CPU核数(or略小于CPU核数)
多线程合理值
CPU密集计算,逻辑判断多进程CPU核数(or略小于CPU核数)
多线程1

GIL全局锁:是python多线程。

多进程设置的大小与CPU核数的关系

在Python中,多进程的数量可以根据CPU核数来设置,以充分利用计算资源并提高程序的性能。通常情况下,可以将多进程的数量设置为机器的CPU核数,或者略少于CPU核数,以避免过度竞争资源而导致性能下降。

以下是一些关于Python多进程设置大小与CPU核数的一般准则:

1. CPU核数:首先,你可以使用`multiprocessing`模块中的`cpu_count()`函数来获取机器的CPU核数。例如:

import multiprocessing

num_cpus = multiprocessing.cpu_count()

2. 多进程数量:根据机器的CPU核数,你可以将多进程的数量设置为相应的值。通常情况下,将多进程数量设置为CPU核数是一个合理的选择。例如:

num_processes = num_cpus

3. 考虑资源竞争:在设置多进程数量时,需要考虑到每个进程所需的资源(如内存、I/O等)。如果每个进程需要较多的资源,可以将多进程数量设置为略少于CPU核数,以避免过度竞争资源而导致性能下降。

需要注意的是,多进程的设置也取决于具体的应用场景和任务类型。有时候,根据具体情况进行实验和调整,找到最佳的多进程数量可能是更好的选择。此外,还可以考虑使用线程(`threading`模块)来实现并发操作,具体取决于任务的性质和需求。

多线程设置的大小与CPU核数的关系

在Python中,多线程的设置大小与CPU核数之间的关系是相对简单的。由于Python的全局解释器锁(GIL)机制限制了多线程的并行执行,因此多线程并不能充分利用多核处理器的能力。

在Python中,多线程适用于I/O密集型任务,如网络请求、文件读写等,因为这些任务通常会涉及等待时间而在等待的过程中,其他线程可以继续执行。因此,对于I/O密集型任务,可以将多线程的数量设置为适当的值,以充分利用CPU的等待时间。

然而,对于CPU密集型任务,由于GIL的存在,多线程并不能实现真正的并行加速。在这种情况下,多线程的数量增加并不会提高程序的性能,反而可能由于线程之间的频繁切换而导致性能下降。因此,在CPU密集型任务中,通常建议将多线程的数量设置为1,以避免不必要的开销。

综上所述,多线程的设置大小与CPU核数之间的关系在Python中并不直接相关。对于I/O密集型任务,可以适当增加多线程的数量以充分利用CPU的等待时间;对于CPU密集型任务,通常将多线程的数量设置为1即可需要根据具体的应用场景和任务类型来确定最佳的多线程设置。

参考:

python多进程 - 新战鲸的文章 - 知乎

多线程和进程比较

对于IO密集型,多线程效率高于多进程;

对于计算密集型任务,多进程效率高于多线程。

代码如下:

# -*- coding: utf-8 -*-
""" 
@Time:        2023/4/18 14:42
@Author:      CookieYang
@FileName:    threadVsProcess.py
@SoftWare:    PyCharm
@brief:       功能简介
"""
import time
from threading import Thread
from multiprocessing import Process


def f1():
    # time.sleep(1)  #io密集型
    # 计算型:
    n = 10
    for i in range(10000000):
        n = n + i

if __name__ == '__main__':
    # 查看一下100个线程执行100个任务的执行时间
    t_s_time = time.time()
    t_list = []
    for i in range(100):
        t = Thread(target=f1,)
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    t_e_time = time.time()
    t_dif_time = t_e_time - t_s_time
    print('===================================')
    # 查看一下100个进程执行同样的任务的执行时间
    p_s_time = time.time()
    p_list = []
    for i in range(100):
        p = Process(target=f1,)
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time
    print('多线程的执行时间:',t_dif_time)
    print('多进程的执行时间:',p_dif_time)

 

Ubuntu判断进程、线程是IO密集型还是计算密集型 

判断方式(看最后的):

如果voluntary_ctxt_switches 远远小于 nonvoluntary_ctxt_switches,就表示该任务是计算密集型的。

反之voluntary_ctxt_switches 远远大于 nonvoluntary_ctxt_switches,就表示该任务是io密集型的。 

进程池

简单用了一下multiprocessing的进程池,非阻塞的apply_async版本,代码如下:

# -*- coding: utf-8 -*-
""" 
@Time:        2023/4/18 14:31
@Author:      CookieYang
@FileName:    multiprocess00L.py
@SoftWare:    PyCharm
@brief:       功能简介
"""

# coding: utf-8
import multiprocessing
import time


def func():
    msg = "ok"
    print("msg:", msg)
    time.sleep(0.01)
    print("end")


if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=3)
    for i in range(20):
        msg = "hello %d" % (i)
        pool.apply_async(func)  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去

    print("wait close~~~~~~~~~~~~~~~~~~~~~~")
    pool.close()
    pool.join()  # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
    print("done")

还有map版本的:

# -*- coding: utf-8 -*-
""" 
@Time:        2023/4/18 14:25
@Author:      CookieYang
@FileName:    multiprocessL.py
@SoftWare:    PyCharm
@brief:       功能简介
"""
import time
from multiprocessing import Pool


def f(x):
    time.sleep(10)
    # n = 10
    # for i in range(10000000):
    #     n = n + i
    return x * x


if __name__ == '__main__':
    with Pool() as p:
        max_count = 10000
        time1 = time.time()
        res = p.map(f, range(1, max_count + 1))
        print(sum(res))
        time2 = time.time()
        print(f"{max_count},耗时:{time2 - time1:.2f}秒")

并发是指多进程还是多线程

python并发是指多进程还是多线程。

Python中的并发可以指多进程并发和多线程并发,两者都是实现并发执行的方式,但有一些区别。

多进程并发是通过创建多个独立的进程来实现的,每个进程有自己独立的内存空间和资源,它们可以并行执行不同的任务。多进程并发可以充分利用多核处理器的能力,适用于CPU密集型任务。在Python中,可以使用`multiprocessing`模块来实现多进程并发。

多线程并发是在同一个进程内创建多个线程来执行任务,这些线程共享进程的内存空间和资源。由于Python的全局解释器锁(GIL)机制的存在,多线程并不能实现真正的并行执行,只能在单个CPU核上进行切换执行。因此,多线程并发适用于I/O密集型任务,如网络请求、文件读写等。在Python中,可以使用`threading`模块来实现多线程并发。

需要根据具体的应用场景和任务类型选择适合的并发方式。对于CPU密集型任务,多进程并发可能更适合;对于I/O密集型任务,多线程并发可能更适合。同时,还可以结合多进程和多线程的方式来实现更高效的并发执行,例如使用`concurrent.futures`模块中的线程池和进程池。

如何理解并发

并发是指在同一时间段内,多个任务或操作同时进行或交替执行的能力。它是一种并行执行的概念,但并发的实现方式可以有多种。

在计算机领域,并发通常用于提高系统的性能和资源利用率。通过并发执行,可以使多个任务或操作在同一时间段内共享计算机的资源,如CPU、内存、磁盘等,从而提高系统的吞吐量和响应能力。

并发可以通过多进程、多线程、协程等方式实现。多进程并发是通过创建多个独立的进程来执行任务,每个进程有自己独立的资源和执行环境。多线程并发是在同一个进程内创建多个线程来执行任务,这些线程共享进程的资源。协程是一种轻量级的线程,可以在同一个线程内实现并发执行,通过协作的方式进行任务切换。

并发的好处在于可以提高系统的响应速度、资源利用率和用户体验。例如,在一个网络服务器中,通过并发处理多个客户端请求,可以提高服务器的吞吐量和并发连接数。在一个图像处理应用中,通过并发执行多个图像处理任务,可以加快处理速度。

然而,并发也带来了一些挑战,如资源竞争、同步和通信等问题。在并发编程中,需要注意对共享资源的访问控制,避免数据竞争和死锁等问题。同时,还需要合理地设计任务调度和通信机制,以确保并发执行的正确性和效率。

综上所述,理解并发意味着理解在同一时间段内多个任务或操作的同时执行或交替执行的能力,以及实现并发的不同方式和应用场景。

并发与并行

并发和并行(图解) - deeplearning的文章 - 知乎(并发,并行的概念看该链接)

总结

  1. 并发针对单核 CPU 而言,它指的是 CPU 交替执行不同任务的能力;
  2. 并行针对多核 CPU 而言,它指的是多个核心同时执行多个任务的能力。
  3. 单核 CPU 只能并发,无法并行;换句话说,并行只可能发生在多核 CPU 中。
  4. 在多核CPU中,并发和并行一般都会同时存在,它们都是提高 CPU 处理任务能力的重要手段。

我们现在使用的应该都是多核CPU了。

大概理解一下,并行指的是每个核都执行1个任务。并发指的是在每个核内部可以同时交替执行多个任务。

并发+并行

执行任务的数量恰好等于 CPU 核心的数量,是一种理想状态。

但是在实际场景中,处于运行状态的任务是非常多的,尤其是电脑和手机,开机就几十个任务,而 CPU 往往只有 4 核、8 核或者 16 核,远低于任务的数量.

这个时候就会同时存在并发和并行两种情况:所有核心都要并行工作,并且每个核心还要并发工作。例如,一个双核 CPU 要执行四个任务,它的工作状态如下图所示:

每个核心并发执行两个任务,两个核心并行的话就能执行四个任务。当然也可以一个核心执行一个任务,另一个核心并发执行三个任务,这跟操作系统的分配方式,以及每个任务的工作状态有关系。

引子

一开始梳理这些关系的原因。

服务端开30个进程+100个线程。
这里引发的思考,多线程是不是针对客户端来说的呢?就是你调用模型的时候你可以开多线程,请求服务端的域名呗。
就服务端(模型部署本身来说),有一套pipeline,就是下载图片+图像处理+前向推理+softmax返回结果,这个流程怎么开多线程呢?
梳理完基础概念之后我的回答:请求下载图片的时候,请求访问下图链接,这是IO密集型任务,可以通过多线程并发来提高效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/114323.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka基本原理、生产问题总结及性能优化实践 | 京东云技术团队

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&a…

逻辑(css3)_强制不换行

需求 如上图做一个跑马灯数据,时间、地点、姓名、提示文本字数都不是固定的。 逻辑思想 个人想法是给四个文本均设置宽度,不然会出现不能左对齐的现象。 此时四个文本均左对齐, 垂直排列样式也比较好看,但是出现一个缺点&#…

STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式)

STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式) 一、所用材料: STM32F103C6T6最小系统板 STM32CUBEMX(HAL库软件) MDK5 示波器或者逻辑分析仪 二、所学内容: 通过定时器TIM的输出比较模式得到预…

基于深度学习的视频多目标跟踪实现 计算机竞赛

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 …

【设计模式】第11节:结构型模式之“装饰器模式”

一、简介 装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外,装饰器模式还有一个特点,那就是可以对原始类嵌套使用多个装饰器。…

开槌在即:陈可之油画|《我的星辰》

《我的星辰》 尺寸:46x46cm 陈可之2020年绘 “星辰大海,梦想自有梦想的力量,仰望在银河的想象,我们启航。”读着画名,凝视着画,脑海里回荡着《星辰大海》的旋律。油画《我的星辰》是陈可之先生“心宇宙”系…

AI开源 - LangChain UI 之 Flowise

原文:AI开源 - LangChain UI 之 Flowise 一、Flowise 简介 Flowise 是一个为 LangChain 设计的用户界面(UI),使得使用 LangChain 变得更加容易(低代码模式)。 通过拖拽可视化的组件,组建工作流,就可以轻…

企业几种快速传输大文件的使用方法,你GET到了吗

在当今信息化时代,数据已经成为企业最重要的资产之一。大文件的传输在企业的日常工作中是一个常见需求,无论是用于内部协作还是与外部合作伙伴之间的数据交流,都需要高效、安全、稳定地传输大文件,以确保数据的完整性和及时性。本…

HarmonyOS鸿蒙原生应用开发设计- 隐私声明

HarmonyOS设计文档中,为大家提供了独特的隐私声明,开发者可以根据需要直接引用。 开发者直接使用官方提供的隐私声明内容,既可以符合HarmonyOS原生应用的开发上架运营规范,又可以防止使用别人的内容产生的侵权意外情况等&#xff…

DataCastle企业风险算法赛实战(进阶难度)

目录 一、数据读取及分析 1、数据读取 2、数据分析 二、数据挖掘 三、模型构建及评估 四、划重点 推荐相关文章 去年在DataCastle上参加了华录杯算法赛,初赛前10、进复赛就没打了。相比于之前文章 kaggle风控建模实战(文末附链接)&…

Windows11恢复组策略编辑器功能的方法

原因分析 日常工作学习中,对 Windows 计算机上的问题进行故障排除时,有些高级用户经常使用组策略编辑器轻松修复它。通过其分层结构,您可以快速调整应用于用户或计算机的设置。如果搜索结果中缺少组策略编辑器,则可能必须使用注册表编辑器作为疑难解答工具,这是一种更复杂…

【windows】添加共享打印机错误:0x000006ba

【问题描述】 添加共享打印机的时候,提示操作无法完成。 错误:0x000006ba。 【解决方法】 一、看下服务里 打印机服务Print Spooler是否正常启动; 二、打印机服务Print Spooler没有的话;(开始–运行—services.msc 回…

vue3+ts封装图标选择组件

概要 讲解在vue3的项目中封装一个简单好用的图标选择组件。 效果 第一步&#xff0c;准备图标数据 数据太多&#xff0c;大家去项目中看。项目地址https://gitee.com/nideweixiaonuannuande/xt-admin-vue3 第二步&#xff0c;页面与样式编写 <template><div>…

【IDEA使用maven package时,出现依赖不存在以及无法从仓库获取本地依赖的问题】

Install Parent project C:\Users\lxh\.jdks\corretto-1.8.0_362\bin\java.exe -Dmaven.multiModuleProjectDirectoryD:\学习\projectFile\study\study_example_service "-Dmaven.homeD:\Program Files\JetBrains\IntelliJ IDEA2021\plugins\maven\lib\maven3" "…

Flink日志采集-ELK可视化实现

一、各组件版本 组件版本Flink1.16.1kafka2.0.0Logstash6.5.4Elasticseach6.3.1Kibana6.3.1 针对按照⽇志⽂件⼤⼩滚动⽣成⽂件的⽅式&#xff0c;可能因为某个错误的问题&#xff0c;需要看好多个⽇志⽂件&#xff0c;还有Flink on Yarn模式提交Flink任务&#xff0c;在任务执…

Linux基础环境开发工具的使用(yum,vim,gcc,g++)

Linux基础环境开发工具的使用[yum,vim,gcc,g] 一.yum1.yum的快速入门1.yum安装软件2.yum卸载软件 2.yum的生态环境1.操作系统的分化2.四个问题1.服务器是谁提供的呢?2.服务器上的软件是谁提供的呢?3.为什么要提供呢?4.yum是如何得知目标服务器的地址和下载链接呢?5.软件源 …

VMware打开centos黑屏解决方法汇总以及解决出现的bug(Centos7系统网络异常等)

VMware打开centos黑屏解决方法汇总 前言&#xff1a;一. VMware打开centos黑屏解决方法汇总一 .情况情况一&#xff1a;情况二情况三 二. 解决方法最简单的方法&#xff1a;一. 以管理员权限在命令行执行1. 管理员身份运行cmd2. 输入“netsh winsock reset”,回车3. 重启电脑即…

Python条件判断的运用

问题 在生活中&#xff0c;我们可以通过判断条件是否成立&#xff0c;来决定执行哪个分支。选择语句有多种形式&#xff1a;if语句&#xff0c;if-else语句&#xff0c;if-elif-else语句等。 Python使用if条件判断语句来实现条件判断时&#xff0c;可以在多个循环中实现对问题的…

Linux-----nginx的简介,nginx搭载负载均衡以及nginx部署前后端分离项目

目录 nginx的简介 是什么 nginx的特点以及功能 Nginx负载均衡 下载 安装 负载均衡 nginx的简介 是什么 Nginx是一个高性能的开源Web服务器和反向代理服务器。它的设计目标是为了解决C10k问题&#xff0c;即在同一时间内支持上万个并发连接。 Nginx采用事件驱动的异…