多进程完成多任务

多进程完成多任务

多进程就是可以实现多个任务在同一时间一起执行

多任务的两种表现形式

  • 并发

    在一段时间内交替去执行多个任务

    例如单核cpu处理多任务,操作系统会轮流让各任务交替执行0.01s微信,0.01sqq,0.01s浏览器,0.01s网易云,因为时间很短,所以宏观上不会感觉卡顿

    在这里插入图片描述

  • 并行

    在一段时间内真正的同时一起执行多个任务

    多核处理器执行多任务就是并行

    img

三、进程

3.1进程的概念:

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

img

在这里插入图片描述

1.导入进程包 import multiprocesing

2.创建子进程并指定执行的任务

进程对象 = multiprocessing.Process()

sub_process=multiprocessing.Process(target=任务名)

3.启动进程执行任务

进程对象.start()

sub_process.start()

单任务和多任务的例子

import time

def sing():
    for i in range(3):
        print("唱歌。。。")
        time.sleep(0.5)
def dance():
    for i in range(3):
        print("跳舞。。。")
        time.sleep(0.5)
if __name__ == '__main__':
    time1 = time.time()
    sing()
    dance()
    print(time.time()-time1)
    
    
    
​ 输出结果

唱歌。。。
唱歌。。。
唱歌。。。
跳舞。。。
跳舞。。。
跳舞。。。
3.0027265548706055

import multiprocessing
import time

def sing():
    for i in range(3):
        print("唱歌。。。")
        time.sleep(0.5)
def dance():
    for i in range(3):
        print("跳舞。。。")
        time.sleep(0.5)
if __name__ == '__main__':
    time1 = time.time()
    s1 = multiprocessing.Process(target=sing)
    d1 = multiprocessing.Process(target=dance)
    s1.start()
    d1.start()
    s1.join() #这个方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步
    d1.join()
    print(time.time()-time1)

    
输出结果

唱歌。。。
跳舞。。。
唱歌。。。
跳舞。。。
唱歌。。。
跳舞。。。
1.7515902519226074

进程执行带有参数的任务

multiprocessing.Process(target=任务名,args=(3,)),元组参数args=()

multiprocessing.Process(target=任务名,kwargs={“num”:3}),字典参数参数kwargs={}

import multiprocessing
import time

def sing(name, num):
    for i in range(num):
        print("%s在唱歌。。。"%name)
        time.sleep(0.5)
def dance(num):
    for i in range(num):
        print("跳舞。。。")
        time.sleep(0.5)
if __name__ == '__main__':
    # 以元组形式传参
    s1 = multiprocessing.Process(target=sing, args=('小明', 3))
    # 以字典形式传参
    d1 = multiprocessing.Process(target=dance, kwargs={"num": 5, })
    s1.start()
    d1.start()

进程的注意点

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

3.6获取进程编号

进程编号的作用:

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

获取进程编号的两种方式:

  • 获取当前进程编号
  1. os.getpid()
  • 获取当前父进程编号
  1. os.getppid()
import multiprocessing
import time
import os
def sing(name, num):
    print("唱歌进程的编号: ", os.getpid())
    print("唱歌进程的父进程的编号: ", os.getppid())
    for i in range(num):
        print("%s在唱歌。。。"%name)
        time.sleep(0.5)
def dance(num):
    print("跳舞进程的编号: ", os.getpid())
    print("跳舞进程的父进程的编号: ", os.getppid())
    for i in range(num):
        print("跳舞。。。")
        time.sleep(0.5)
if __name__ == '__main__':
    print("主进程的编号: ", os.getpid())
    # 以元组形式传参   顺序和参数顺序一致
    s1 = multiprocessing.Process(target=sing, args=('小明', 3))
    # 以字典形式传参   key和参数名保持一致
    d1 = multiprocessing.Process(target=dance, kwargs={"num": 5, })
    s1.start()
    d1.start()


主进程的编号: 10620
唱歌进程的编号: 18412
唱歌进程的父进程的编号: 10620
小明在唱歌。。。
跳舞进程的编号: 9924
跳舞进程的父进程的编号: 10620
跳舞。。。
小明在唱歌。。。
跳舞。。。
小明在唱歌。。。
跳舞。。。
跳舞。。。
跳舞。。。

3.7进程的注意点

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

import time
import multiprocessing

def work():
    for i in range(10):
        print("工作中。。。。")
        time.sleep(0.2)

if __name__ == '__main__':
    work_process = multiprocessing.Process(target=work)
    work_process.start()

    time.sleep(1)
    print("主进程执行结束")



输出结果:

工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`主进程执行结束`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。
  • 设置守护主进程

  • 主进程结束后子进程销毁不会继续执行子进程中剩余的任务

import time
import multiprocessing

def work():
    for i in range(10):
        print("工作中。。。。")
        time.sleep(0.2)

if __name__ == '__main__':
    # 设置守护主进程,主进程执行完成,则结束
    # 方式1
    work_process = multiprocessing.Process(target=work, daemon=True)
    # 方式2
    # work_process.daemon = True
    work_process.start()

    time.sleep(1)
    print("主进程执行结束")

输出结果:

工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`工作中。。。。`
`主进程执行结束

3-8案例-多进程实现视频文件夹多任务拷贝

1.需求分析:

  • ​ 目标文件夹是否存在,如果不存在就创建,存在则不创建

  • ​ 遍历源文件夹中所有文件,并拷贝到目标文件夹

  • ​ 采用进程实现多任务,并完成拷贝

2.实现步骤

  • 定义源文件夹所在的路径,目标文件夹所在路径

  • source_dir="E:\文档\论文"
    dest_dir="C:/Users/13664/Desktop/test"
    
  • 创建目标文件夹

  • try:
    	os.mkdir(dest_dir)
    except:
    	print("目标文件夹已存在,未创建")
    
  • 通过os.listdir获取源目录中的文件列表

  • file_list=os.listdir(source_dir)
    print(file_list)
    
  • 遍历每个文件,定义一个函数,专门实现文件拷贝

  • for file_name in file_list:
    copy_work(file_name,source_dir,dest_dir)
    
  • 采用进程实现多任务,完成高并发拷贝

  • sub_process=multiprocessing.Process(target=copy_work,args=(file_name,source_dir,dest_dir))
    sub_process.start()
    
    import multiprocessing
    import  os
    def copy_file(file_name, source_dir, dest_dir):
        """
    
        :param file_name:文件名
        :param source_dir:源文件夹
        :param dest_dir:目标文件夹
        :return:
        """
        #1拼接源文件路径和目标文件路径
        source_path=source_dir+"/"+file_name
        dest_path=dest_dir+"/"+file_name
    
        #2.打开源文件和目标文件
        with open(source_path,"rb") as source_file:
            with open(dest_path,"wb") as dest_file:
                #循环读取源文件到目标路径
                while True:
                    #每次读1k数据
                    data=source_file.read(1024)
                    if data:
                        dest_file.write(data)
                    else:
                        break
    
    
    if __name__ == "__main__":
        #1 定义源文件夹和目标文件夹
        source_dir = "E:/文档/论文"
        dest_dir = "C:/Users/13664/Desktop/test"
    
        #2 创建目标文件夹
        try:
            os.mkdir(dest_dir)
        except:
            print("目标文件夹已存在,未创建")
    
        #3 通过os.listdir获取源目录中的文件列表
        file_list = os.listdir(source_dir)
    
        #4 遍历每个文件,定义一个函数,专门实现文件拷贝
        for file_name in file_list:
    
            # 单任务拷贝
            copy_file(file_name, source_dir, dest_dir)
    
            # #多任务拷贝
            # sub_process = multiprocessing.Process(target=copy_file, args=(file_name, source_dir, dest_dir))
            # sub_process.start()
    

    四、多线程完成多任务

    1.线程的介绍

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

    在这里插入图片描述

  • 2.多线程的作用

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-swiDMsLz-1646140612349)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301203036094.png)]

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXtTR19R-1646140612350)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301203136855.png)]

3.线程的创建步骤

1.导入线程模块

import threading

2.通过线程类创建线程对象

线程对象=threading.Thread(target=任务名)

3.启动线程执行任务

线程对象.start()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nurMPW1f-1646140612352)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301203717406.png)]

线程执行带参数的任务

和进程一样

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLGqXNDk-1646140612353)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301204854660.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7n6H0vU-1646140612354)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301204822377.png)]

主线程和子线程结束顺序

主线程会等待所有子线程结束后再结束

设置主线程守护后,主线程不会等待子线程执行,会直接结束任务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hNRNTiP5-1646140612356)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20220301205147226.png)]

线程间的执行顺序

import  time
import  threading
def task():
    time.sleep(1)
    #获取当前线程的线程对象
    thread=threading.current_thread()
    print(thread)

if __name__=="__main__":
    for i in range(5):
        sub_thread=threading.Thread(target=task)
        sub_thread.start()

输出结果:
<Thread(Thread-2, started 4900)><Thread(Thread-5, started 29860)>
<Thread(Thread-1, started 23072)>
<Thread(Thread-4, started 22840)>

<Thread(Thread-3, started 14732)>

发现输出结果连换行都不统一了

进程和线程对比

关系对比

线程是依附在进程里面的,没有进程就没有线程
一个进程默认提供一条线程,进程可以创建多个线程

区别对此

创建进程的资源开销要比创建线程的资源开销要大
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
线程不能够独立执行,必须依存在进程中

优缺点对比

  • 进程优缺点:
    优点:可以用多核(同时开启QQ和微信,采用多核并行方式使用资源)
    缺点:资源开销大
  • 线程优缺点:
    优点:资源开销小
    缺点:不可用多核(一个进程会占用一个核,一个进程中的多个进程只能采用并发的方式依次使用这个核的资源)

(Thread-2, started 4900)><Thread(Thread-5, started 29860)>
<Thread(Thread-1, started 23072)>
<Thread(Thread-4, started 22840)>

<Thread(Thread-3, started 14732)>

发现输出结果连换行都不统一了

进程和线程对比

关系对比

线程是依附在进程里面的,没有进程就没有线程
一个进程默认提供一条线程,进程可以创建多个线程

区别对此

创建进程的资源开销要比创建线程的资源开销要大
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
线程不能够独立执行,必须依存在进程中

优缺点对比

  • 进程优缺点:
    优点:可以用多核(同时开启QQ和微信,采用多核并行方式使用资源)
    缺点:资源开销大
  • 线程优缺点:
    优点:资源开销小
    缺点:不可用多核(一个进程会占用一个核,一个进程中的多个进程只能采用并发的方式依次使用这个核的资源)
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

甲乙zzu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值