python多任务(进程+线程+对比)

目录

python多任务

多进程

进程概念

多进程作用

进程的创建

进程执行带有参数的任务

获取进程编号

设置守护主进程

多线程

线程概念

线程的创建步骤

线程执行有参数的任务

主线程和子线程的结束顺序

线程之间的执行顺序

线程和进程的对比


python多任务

使用多任务的作用在于充分利用CPU资源,提高程序执行的效率,通常有并发和并行两种形式

实现方式:

  • 多进程

  • 多线程

多进程

进程概念

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

如图,CPU会为进程分配内存、磁盘、网络等等资源

注:一个运行起来的程序至少有一个进程,也可以有多个

多进程作用

比如,程序中有两个函数AB, 多进程可以实现AB两个函数同时运行,这样就提高了效率。

程序运行中会产生一个主进程,若创建一个子进程,二者同时运行就实现了多进程。

进程的创建

1、 导入进程包

import multiprocessing

2、创建进程对象

进程对象=multiprocessing.Process(target=任务名)
参数还有 name:进程名,一般不用设置 group: 进程组,只能用None

3、启动进程执行任务

进程对象.start()

示例代码01

import multiprocessing
import time
def sing():
    for i in range(2):
        print('唱歌')
        time.sleep(0.5)
def dance():
    for i in range(2):
        print('跳舞')
        time.sleep(0.5)
if __name__=='__main__':
    sing_process=multiprocessing.Process(target=sing)
    dance_process=multiprocessing.Process(target=dance)
    
    sing_process.start()
    dance_process.start()
-----------------------------------------------------------------------------------------
结果:
唱歌
跳舞
唱歌
跳舞      
  

进程执行带有参数的任务

方式:

(需要注意的是,元组传参里面必须跟逗号

(字典的键必须和参数名一样,键对应的值就是传入的参数值)

示例代码02

import multiprocessing
import time
def sing(num):
    for i in range(num,name):  #num形参 name形参
        print(name)
        print('唱歌')
        time.sleep(0.5)
def dance(num):
    for i in range(num,name):  #num形参 name形参
        print(name)
        print('跳舞')
        time.sleep(0.5)
if __name__=='__main__':
    sing_process=multiprocessing.Process(target=sing,args=(3,'小明'))  
    #元组方式传参,按顺序
    dance_process=multiprocessing.Process(target=dance,kwargs={'name':'小红','num':2}) 
    #字典方式传参,可不按顺序,键名匹配即可
    
    sing_process.start()
    dance_process.start()
-----------------------------------------------------------------------------------------
结果:
小明
唱歌
小红
跳舞
小明
唱歌
小红
跳舞

获取进程编号

进程编号的作用:

当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理实际上每个进程都是有自己编号的.

获取进程编号的方式:

  • 获取当前进程编号

    os.getpid()

  • 获取当前父进程的编号

    os.getppid()

示例代码03

import os
import multiprocessing
import time
def sing(num):
    print('唱歌进程编号:',os.getpid())                  #获得当前唱歌进程的编号
    print('唱歌进程的父进程编号(即主进程):',os.getppid())  #获得唱歌进程的父进程的编号
    for i in range(num,name):  #num形参 name形参
        print(name)
        print('唱歌')
        time.sleep(0.5)
def dance(num):
    for i in range(num,name):  #num形参 name形参
        print(name)
        print('跳舞')
        time.sleep(0.5)
if __name__=='__main__':
    print('主进程编号:',os.getpid())  #获得主进程的编号,发现和唱歌进程的父进程编号一致
    sing_process=multiprocessing.Process(target=sing,args=(3,'小明'))  
    #元组方式传参,按顺序
    dance_process=multiprocessing.Process(target=dance,kwargs={'name':'小红','num':2}) 
    #字典方式传参,可不按顺序,键名匹配即可
    
    sing_process.start()
    dance_process.start()
-----------------------------------------------------------------------------------------
结果:(省略部分)
主进程编号:79412
唱歌进程编号:79414
唱歌进程的父进程编号(即主进程):79412

设置守护主进程

线程和进程的对比

  • 主进程会等待所有的子进程执行结束再结束

  • 设置守护主进程

    (主进程退出后子进程直接销毁,不再执行未完成的子进程代码,如QQ退出聊天框也会结束)

    方式:

    子进程对象.daemon=True
    import time
    import multiprocessing
    def work():
        for i in range(10):
            print('工作中')
            time.sleep(0.2)  #那么此进程共执行2秒
    if __name__=='__main__':
        work_process=multiprocessing.Process(target=work)
        work_process.daemon=True  #!!!!!!!在这里设置daemon为True就完事了!!!!!!!!!
        work_process.start()
        
        time.sleep(1)  #意思是主进程只执行1秒,那就比work的子进程短1秒
        print('主进程执行完成!')
    -------------------------------------------------------------------------------------- 工作中
    工作中
    工作中
    工作中
    工作中  
    主进程执行完成!   # 显然,子进程本来该有10次,这里未完成

    多线程

    线程概念

    多线程是python实现多任务的一种方式,是程序执行的最小单位,同属一个进程的多个线程共享进程所拥有的全部资源

    线程的创建步骤

    1、 导入线程模块

    import threading

    2、创建线程对象

    线程对象=threading.Thread(target=任务名)
    参数还有 name:进程名,一般不用设置 group: 进程组,只能用None

    3、启动线程执行任务

    线程对象.start()

    示例代码04

    import threading
    def sing():
        for i in range(2):
            print('唱歌')
            time.sleep(0.5)
    def dance():
        for i in range(2):
            print('跳舞')
            time.sleep(0.5)
    if __name__=='__main__':
        sing_thread=threading.Thread(target=sing)
        dance_thread=threading.Thread(target=dance)
        sing_thread.start()
        dance_thread.start()
    -----------------------------------------------------------------------------------------
    唱歌    #实际上,唱歌和跳舞是同时打出的,那么只需要三次就执行完毕了
    跳舞
    唱歌
    跳舞
    唱歌
    跳舞

    线程执行有参数的任务

    方式:

    他们的使用方式和进程是一样的

    示例代码05

     

    import threadingthreading
    import time
    def sing(num):
        for i in range(num,name):  #num形参 name形参
            print(name)
            print('唱歌')
            time.sleep(0.5)
    def dance(num):
        for i in range(num,name):  #num形参 name形参
            print(name)
            print('跳舞')
            time.sleep(0.5)
    if __name__=='__main__':
        sing_process=threading.Process(target=sing,args=(3,'小明'))  
        #元组方式传参,按顺序
        dance_process=threading.Process(target=dance,kwargs={'name':'小红','num':2}) 
        #字典方式传参,可不按顺序,键名匹配即可
        
        sing_process.start()
        dance_process.start()
    -----------------------------------------------------------------------------------------
    结果:
    小明
    唱歌
    小红
    跳舞
    小明
    唱歌
    小红
    跳舞

    主线程和子线程的结束顺序

    和进程类似,主线程会在所有的子线程结束后再结束,同样的,我们也可以设置守护主线程

    方法1

    #在创建线程对象的时候, 指定daemon=True
    sing_process=threading.Process(target=sing,args=(3,'小明'),daemon=True)

    方法2

    #使用函数设置
    sing_process.setDaemon(True)

    线程之间的执行顺序

  • 线程之间的执行是无序的,由CPU调度某个线程执行

  • 获取当前的线程信息

    #通过current_thread方法获取线程对象
    current=threading.current_thread()
    #通过current对象可知线程的相关信息,例如被创建的顺序、名称
    print(current)

  • 关系对比

    1.线程是依附在进程里面的,没有进程就没有线程。

    2.一个进程默认提供一条线程,进程可以创建多个线程。  

     

  • 区别对比

    1.创建进程的资源开销要比创建线程的资源开销要大

    2.进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位

    3.线程不能独立执行,必须依附于进程

    (进程注重资源分配,线程注重CPU调度)

  • 优缺点对比

    1.进程优缺点:

    优点:可以用多核

    缺点:资源开销大

    2.线程优缺点:

    优点:资源开销小

    缺点:不能使用多核

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MUNG东隅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值