一、进程的介绍
定义
- 进程是计算机中的程序关于某数据集合上的⼀次运⾏活动,是系统进⾏资源分配和调度的基本 单位,是操作系统结构的基础。
- 进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体
特点
- 进程是⼀个实体。每⼀个进程都有它⾃⼰的地址空间,⼀般情况下,包括⽂本区域(text region)、数据区域(data region)和堆栈(stack region)。
进程是⼀个“ 执⾏中的程序”
进程是操作系统中最基本重要的概念 - 父进程创建的叫子进程,每个子进程都有一个不重复的ID号(pid),对进程进行标识。
子进程与父进程的 资源+代码 一致。子进程从父进程继承了多个值的拷贝。
进程状态介绍
线程与进程的对比
- 进程:正在执⾏的程序。动态的,暂时的
- 程序:没有执⾏的代码,是⼀个静态的,永久的
- 根本的区别
- 进程:操作系统资源分配的基本单位
- 线程:任务调度和执行的基本单位
- 开销
- 进程:通过赋值代码+资源创建子进程 每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销
- 线程:同一份代码里 创建线程,共享内存 开销较小
- 分配内存
- 进程:系统在运行的时候为每个进程分配不同的内存空间
- 线程:线程所使用的资源是它所属的进程的资源
- 包含关系
- 进程:一个进程可以拥有多个线程
- 线程:线程是进程的一部分
二、进程实现
(一)进程方法介绍
multiprocessing.Process
- 给进程下定义
- multiprocessing.Process(target=函数名, args=元组 , kwargs=字典,name)
- target:函数名可以填类方法 或 A().实例方法或A.类方法
会自动调用,不需要加() - args:位置传参 元组,一一对应
- kwargs:关键字传参 字典的,字典的key就是函数的形参,value就是要传的值
- name:子进程名称
- target:函数名可以填类方法 或 A().实例方法或A.类方法
t.start()
- 子进程的创建与运行
- 当调用Process的时候,不会创建进程
- start()的时候,才会创建线程以及开始运行这个进程
- start的时候就会调用run
os.getpid() 、os.getppid()
- 获得进程的id
- getpid:子进程id getppid:父进程id
(二)进程创建实现方法
在任务管理器可以看到创建成功的过程
三、进程的其他要点
(一)多进程的通信
- 进程之间是不共享全局变量,等同于两个软件之间不共享资源
- 只能通过队列来传输信息
(二)利用队列进行通信
队列介绍
- 队列:排队,先进先出(排队买奶茶)
栈:先进后出(洗碗)
队列分类
- 普通队列 q = queue.Queue(3)
- 进程队列 q = multiprocessing.Queue(2)
- 进程池队列 q = multiprocessing.Manager().Queue(2)
实现队列进行通信
实现函数download中,将list元素保存到队列中
实现函数manage_data中,将list元素从队列中取出,并且添加新的列表中
(三)进程池
引入
- 当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但是如果上百甚至上千个目标,手动的去创建的进程的工作量巨大,此时就可以用到multiprcessing模块提供的Pool方法,也就是进程池
- 初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会传一个新的进程用来执行该请求,但是如果进程池中的进程已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会用到之前的进程来执行新的任务
特点
- 一个进去一个出来的进程号是同一个
进程池创建
- po=multiprocessing.Pool(进程池大小)
- po.apply_async(func, args=(), kwds={}, callback=None,
error_callback=None)
进程池之间的通信–进程池的队列
四、多任务文件夹的复制
-
需求1:实现多任务文件夹的复制
- 获取用户赋值的文件夹的名字
创建一个新的文件夹
获取文件夹所有带拷贝的文件名字
创建进程池
添加拷贝任务
- 获取用户赋值的文件夹的名字
-
需求2:实现进度条
- 1.获取到文件的总数
2.当前已经下载到哪个文件了
3.2/3–>下载进度
- 1.获取到文件的总数