3.python学习笔记:python下的多进程与多线程(一)

如何用 Python 进行多线程与多进程编程:优化 CPU 与 IO 密集型任务 本文探讨了Python中多线程与多进程在优化不同任务类型时的应用。文章指出,由于全局解释器锁(GIL)的限制,多线程适合IO密集型任务(如网络请求、文件读写),而多进程更适合CPU密集型任务(如数值计算)。文中提供了具体代码示例,包括使用threading模块优化文件下载、利用multiprocessing加速数值计算,以及介绍异步编程asyncio在IO任务中的应用。最后总结指出,根据任务类型(CPU/IO密集型)选择合适的并发模型(多进程/多线程/异步),可以显著提升Python程序的执行效率。 阅读详情

python下的多进程与多线程


python多进程

关于多进程与多线程的概念第一个接触是在学习C语言的时候,当时借助stevens的《UNIX环境高级编程》了解了关于进程和线程的相关知识,为现在接触python的同类概念打下了基础。有兴趣的同学也可以阅读这本书。

当我们需要并行的执行多个任务的时候,在python语言中有两种方式:进程分支和线程派生。

在这节中我们将会介绍进程分支的技术,分支的进程是构建平行任务的传统做法,分支的想法基于程序的复制:在最初的阶段,当程序调用分支去开启另外一个程序的时候,操作系统会创建该程序及其在内存中的副本。但是在随后的使用过程中发现,新开启的程序往往执行的任务与原程序没有任何关系,所以操作系统提出了写时复制这样的机制(即只有在原程序的资源被使用的时候才进行拷贝),极大的提高了内存和时间的效率。

在进行了分支操作后,原来的程序副本叫做父进程,而由os.fork创建的副本称为子进程。

下面给出一个多进程的示例:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import os


def create_child():
    print ('hello from child', os.getpid())
    os._exit(0)

if __name__ == '__main__':
    while True:
        new_pid = os.fork()
        if new_pid == 0:
            create_child()
        else:
            print ('hello from parent', os.getpid(), new_pid)
            if raw_input() == 'q':
                break 

注意:
1.使用os.fork()可以产生分支进程,返回值有两个,如果new_pid为0,则该区域的操作是属于子进程的,如果大于0则是属于父进程的操作。

这个os.fork只是对系统代码库的简单封装。

在上述示例中,每个进程运行后很快结束,因此在时间的重叠很少,接下来的示例中我们让进程进行一定时间上的sleep;

#!/usr/bin/env python

#-*-coding:utf-8-*-

import os
import time

def thild_count(count):
    for i in range(count):
        time.sleep(1)
        print('[%s] => %s' % (os.getpid(), i))


if __name__ == '__main__':
    for i in range(5):
        pid = os.fork()
        if pid != 0:
            print('Process %d spawned' % pid)
        else :
            thild_count(5)
            os._exit(0)

    time.sleep(10)
    print('Main process exiting.!')

一般来讲,fork和exec是组合使用的,实现的功能是开启一个新的进程,并且指定其完成新的任务。

如下所示:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import os
import sys

parm  = 0
while True:
    parm += 1
    pid = os.fork()
    if pid == 0:
        os.execlp('python', 'python', 'fork1.py', str(parm))
        assert False, 'error starting program'
    else:
        print ('Child is', pid)
        if raw_input() == 'q':
            break

exec是一组函数的统称,更多的操作如下所示:

os.execv(program, commandlinesequence)
os.execl(program, cmdarg1, cmdarg2, …cmdargN)
os.execlp
os.execvp
os.execle
os.execve
os.execvpe

除了使用fork和exec的组合外,我们还可以使用os.system、os.popen和subprocess模块的方式派生shell命令.


python多线程


线程与进程

线程是开启另外一个任务的另一种方法,他们和程序其他部分并行地调用函数,有时候线程被称做“轻量级进程”,但是他们只能在一个进程中执行。关于进程和线程之间地关系如下所示:

1.性能改善:
因为所有地线程都是在同一个进程中进行,所以他们一般不会因为复制进程而造成其他地开销。

2.简单易用:
生去了进程间通信等复杂细节,量级轻。

3.共享全局内存:
同一进程中的线程之间可以共享全局的资源,但是需要注意同步的问题。

4.可移植性
python的线程工具自动适应平台特用的线程方面的差异,具有一致性接口。


thread模块

thread模块编写的多线程程序更像是面向过程的操作,我们给出如下几个示例;

1.开启多个线程,每个线程打印自己是第几个线程:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import thread

def child(tid):
    print ('Hello from thread', tid)


if __name__ == '__main__':
    i = 0
    while True:
        i += 1
        thread.start_new_thread(child, (i,))
        if raw_input() == 'q':
            break

2.下面我们展示多线程共同抢占stdout标准输出资源的示例,因为stdout也是该程序的公共资源,多个线程同时进行输出,可能会造成显示上的无规则:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import thread
import time

def counter(my_id, count):
    for i in range(count):
        time.sleep(1)
        print('[%s] => %s' % (my_id, i))

if __name__ == '__main__':
    for i in range(5):
        thread.start_new_thread(counter, (i, 5))

    time.sleep(6)
    print ('the main thread exiting...')

显然上述的方案并不能让人满意,我们更希望它能进行一种同步的操作(即当一个线程正在操作stdout时,其他的线程被阻塞掉),代码如下:

#!/usr/bin/env python

#-*-coding:utf-8-*-


import thread
import time 
import mutex


mutex = thread.allocate_lock()

def counter(my_id, count):
    for i in range(count):
        time.sleep(1)
        mutex.acquire()
        print('[%s] => %s' % (my_id, i))
        mutex.release()


if __name__ == '__main__':
   for i in range(5):
       thread.start_new_thread(counter, (i, 5))

   time.sleep(6)

这里我们采用了线程锁的方案,当一个线程对stdout加锁后操作时,其他的线程就会被阻塞掉,直到这个线程操作结束释放锁才能进行响应。这是同步的机制。
除了避免打印上的冲突,线程模块锁还可以作为信号机这样较高层次的同步化范式。

我们使用线程锁组开判断各个子线程是否运行结束,如果结束我们结束主线程:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import thread

stdout_mutex = thread.allocate_lock()
exit_mutexes = [False] * 10

def counter(my_id, count):
    for i in range(count): 
        stdout_mutex.acquire()
        print('[%s] => %s' % (my_id, i))
        stdout_mutex.release()
    exit_mutexes[my_id] = True

if __name__ == '__main__':
   for i in range(10):
       thread.start_new_thread(counter, (i, 20))

   while False in exit_mutexes:
       pass

   print ('the main thread exiting...')

我们还可以通过使用with语句确保在一端嵌套代码块周围执行线程操作,线程锁的上下文管理器在为with语句这一行加锁,然后在语句结束后释放锁,无论是否发生了异常。这是一种很好的保护机制。代码示例如下:

#!/usr/bin/env python

#-*-coding:utf-8-*-

import thread
import time

num_thread = 5
stdout_mutex = thread.allocate_lock()
exit_mutexes = [thread.allocate_lock() for i in range(num_thread)]

def counter(my_id, count, stdout_mutex):
    for i in range(count):
        time.sleep(1 / (my_id + 1))
        with stdout_mutex:
            print('[%s] => %s' % (my_id, i))
    exit_mutexes[my_id].acquire()

if __name__ == '__main__':
    for i in range(num_thread):
        thread.start_new_thread(counter, (i, 10, stdout_mutex))
    while not all(mutex.locked() for mutex in exit_mutexes):
        time.sleep(0.25)
    print ('the main thread is exiting...')

小结:

本章中我们简单的介绍了python的多进程编程以及使用thread模块进行的多线程编程,在下一章节中将会介绍threading模块进行多线程编程,它的操作是较高层次的封装,即使用类和对象对线程进行操作。

面试官:请你讲讲Python多线程多进程 Python多线程多进程 文章目录 并行和并发的概念 线程和进程的概念(来点八股文) PythonGIL锁相关以及历史 多线程编程详解 多进程编程详解(重点) 一、什么是并行和并发? 首先我们来先说一下一个简单的共同点,并行和并发都是完成多任务更加有效率的工具。我们下面用一张图来说明它们的不同点 并发:是指应用能够交替执行不同的任务,其实并发有带你类似于多线程的原理,多线程并非同事执行多个任务,如果你开多个线程执行,就是在你几乎不可察觉的速度不断的去切换这几个线程,以达到“同时执行的效果” 阅读详情

相关推荐

PyTorch实战:5步搞定Res2Net图像分类模型(附完整代码)

本文详细介绍了如何使用PyTorch在5步内构建高性能Res2Net图像分类模型,包括环境配置、核心模块实现、完整网络架构搭建、训练流程优化及模型部署技巧。Res2Net通过多尺度特征融合机制显著提升图像分类性能,附完整代码帮助开发者快速实践。

java5的博客 1022

python用os.system运行多个脚本文件_关于多线程:在Python中与os.system()并行运行两个可执行文件?...

我希望并行运行两个可执行文件a.exe和b.exe,一个接一个地调用。我尝试的时候os.system('a.exe')#some codeos.system('b.exe')b.exe是仅在我杀死a.exe之后才开始?为什么会发生?如何同时运行两者? (我需要做多线程吗?)注意:我在Windows平台上如果我们忽略异常,那么同时运行几个程序很简单:#!/usr/bin/env pythonimpo...

weixin_39580749的博客 2986

研究生课程笔记:软件包在流行病学中的应用(三)——STATA软件

关键词:STATA软件基本操作、STATA对于流行病学研究的实现、STATA对复杂抽样设计样本量计算的实现 一、STATA软件基本操作 这部分网上教程有很多,也可以直接根据stata自带的help功能进行自学,在此只记录课程中提及的功能项。 1. 变量编辑 1.1 赋值:label type(按精度区分) 1) 整型:int(32), short(16), long(32) 2) 实型:flo...

weixin_45463530的博客 2432

python执行系统命令的方法总结

文章目录说明:三个python执行系统命令的方法:1、os.system()2、os.popen()3、subprocess.Popen()4、如何让subprocess.Popen()和os.popen()等待5、总结: 说明: python 将html保存为PDF之一个学习笔记 今天转存HTML为pdf的时候,然后我使用os.system时候出现问题,后来网上搜索python有三种执行命令,结...

zhaojiafu的博客 1709

在ros里给机械臂加上夹爪和底盘后,控制真实机械臂

使用ur3_bringup 可以连接真实机械臂 使用官方的ur3_moveit_planning_execution.launch 可以对机械臂 moveit规划。 但是只有机械臂,没有夹爪。 官方如图: 我把原来的ur3_moveit_config 复制出来,修改 然后把ur3.xacro 等模型文件复制出来修改,修改完之后,有了夹爪,有了底盘。 规划组什么的使用moveit setup assistant 配置过了。 在rviz中可以笛卡尔空间规划了。 ...

超级菜 2715

[LaTeX] 调整参考文献的格式(References),包括作者名缩写,行距,字体,引用顺序等等

在此记录我对LaTeX中参考文献references的尝试,主要涵盖如题几个方面。

the Blog of 等不到天亮丶等时光 4万+

多线程&多进程解析:Python、os、sys、Queue、multiprocessing、threading

当涉及到操作系统的时候,免不了要使用os模块,有时还要用到sys模块。 设计到并行程序,一般开单独的进程,而不是线程,原因是python解释器的全局解释器锁GIL(global interpreter lock),本文最后会讲到。使用进程可以实现完全并行,无GIL的限制,可充分利用多cpu多核的环境。 os/sys模块 1、os模块 os.system() 函数可以启动一个...

418

团子杂记:SAP收入确认工具RAR(Revenue Recognition&Reporting)在新收入准则下的应用

SAP收入确认工具RAR知识分享

Lucas1211的博客 4281

python 线程中使用os.system

场景:thread中执行os.system("wget ....")指令,wget未执行 原因:待解决

wenlei_zhouwl的专栏 2511

N32G003学习——第九章 第三节1 串口 发送

经过第九章前2节的学习,基础打下之后,开始敲代码。

qq_34525008的博客 1030

RTX6000 PRO BLACKWELL 最优 CUDA 版本选择指南(适配 vLLM/SGLang 大模型推理)

本文针对NVIDIA Blackwell架构RTX6000PRO显卡部署vLLM/SGLang大模型推理引擎时的CUDA版本选择问题,提出专业建议。分析表明,CUDA12.9(需搭配552.06+驱动)是最优选择,因其完全支持BW架构特性,且与vLLM/SGLang最新版本深度适配。文章提供详细的Linux环境部署教程,包括驱动升级、CUDA12.9安装及vLLM/SGLang配置步骤,并指出CUDA13.0目前适配不完善,不推荐新手使用。最后给出常见问题解决方案,强调版本匹配对推理性能和稳定性的重要性。

2501_93651177的博客 681

python利用os.system执行多条系统命令

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33695082的博客 1万+

【DRAM存储器五十六】LPDDR5介绍--WCK2CK Leveling和Read gate training

简述LPDDR5 WCK2CK leveling和read gate traning基本原理与操作步骤

highman110的博客 8786

Python之多进程与多线程

前言:为什么有人说 Python 的多线程是鸡肋,不是真正意义上的多线程? 看到这里,也许你会疑惑。这很正常,所以让我们带着问题来阅读本文章吧。问题: 1、Python多线程为什么耗时更长? 2、为什么在Python里面推荐使用多进程而不是多线程? 1 基础知识 现在的PC都是多核的,使用多线程能充分利用CPU来提供程序的执行效率。 1.1 线程 线程是一个基本的CPU执行单元。...

ZONGXP的博客 6万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

python 彻底解读多线程与多进程

title: 多线程与多进程 copyright: true top: 0 date: 2019-03-03 16:16:41 tags: 多线程多进程 categories: Python高阶笔记 permalink: password: keywords: description: 对python的多线程多进程进一步刨析。 真是这样的话,有些话,只有准确的时间准确的地点亲口说出来。现在时间错...

浪子燕青的博客 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

python多进程与多线程

进程程(Process)是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位,通俗理解:一个正在运行的程序就是一个进程。例如:正在运行的qq,微信等他们都是一个进程

渗透之路,攻防之间皆学问 3893

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Python 中的多线程与多进程详解

介绍Python多进程和多线程两种并发编程方式的优势和局限性

weixin_59113684的博客 3476

Python——多线程与多进程

学习python进阶能力,多进程与多线程的能力是必须的,不然真out了。

GeekZW的博客 3035

Python多线程与多进程

python多线程与多进程

尚墨1111的博客 1581

Python中的多进程与多线程详解

【代码】Python中的多进程与多线程详解。

Limiiiing的博客 2645

一文掌握Python多线程与多进程

并发是今天计算机编程中的一项重要能力,尤其是在面对需要大量计算或I/O操作的任务时。Python 提供了多种并发的处理方式,本篇文章将深入探讨其中的两种:多线程与多进程,解析其使用场景、优点、缺点,并结合代码例子深入解读。

2201_75362610的博客 2815

详解Python多线程、多进程

在学习Python的过程中,有接触到多线程编程相关的知识点,先前一直都没有彻底的搞明白。今天准备花一些时间,把里面的细节尽可能的梳理清楚。

2301_76161259的博客 2483

多进程与多线程

多进程是指在操作系统中同时运行多个独立的进程,每个进程都有自己独立的内存空间和系统资源。进程是计算机中执行程序的实体,它包含了程序的代码、数据和执行状态等信息。在多进程编程中,可以将任务分配给不同的进程来并行执行,从而充分利用多核处理器的计算能力。每个进程都有自己的执行环境,它们之间相互独立,互不干扰。多进程之间可以通过进程间通信(IPC)机制来进行数据交换和同步操作。多进程可以提高程序的执行效率,特别适用于执行CPU密集型任务,如图像处理、数据计算、科学计算等。

weixin_39107270的博客 2876

Python中的多线程与多进程指南大全

在Python中,进行性能优化时,我们常常会碰到需要同时执行多个任务的情况。这个时候,使用多线程或多进程技术可以显著提高程序的执行效率。然而,由于Python的全局解释器锁(GIL)的存在,多线程并不能在所有情况下提供预期的性能提升。本文将深入探讨Python中的多线程与多进程,分析它们的适用场景,并通过代码实例展示它们的正确使用方法。

一键难忘的博客 4288

说说Python多线程与多进程的区别?

公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助!...

3293

python3的多进程和多线程设计实现

多线程(threading)和多进程(multiprocessing)差异

tianyuanwo的专栏 825
上一篇: 2.puppet学习笔记:puppet资源file详细介绍
下一篇: 4.python学习笔记:python多线程下的threading模块
linux_player_c
博客等级 码龄13年 214粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值