Python多任务教程:进程、线程、协程
1.进程进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块包含进程的描述信息和控制信息是进程存在的唯一标志。
进程具有的特征:
[*]动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的。
[*]并发性:任何进程都可以同其他进程一起并发执行。
[*]独立性:进程是系统进行资源分配和调度的一个独立单位。
[*]结构性:进程由程序、数据和进程控制块三部分组成。
实现多进程
import multiprocessing
import time
def run1(sleep_time):
while True:
print("-- 1 --")
time.sleep(sleep_time)
def run2(sleep_time):
while True:
print("-- 2 --")
time.sleep(sleep_time)
def main():
# 创建进程对象。
# target:指定线程调用的函数名。注:等号后跟方法名不能加括号,如果加了也能执行函数但threading功能无效
# args:指定调用函数时传递的参数。注:args是一个数组变量参数,只传一个参数时,需要在参数后面添加逗号
p1 = multiprocessing.Process(target=run1, args=(1,))
p2 = multiprocessing.Process(target=run2, args=(1,))
# 启用子进程
p1.start()
p2.start()
# join方法等待子进程执行结束
p1.join()
p2.join()
print("子进程结束")
if __name__ == "__main__":
main()运行上面代码,查看任务管理器python的启动进程数。
https://img-blog.csdnimg.cn/2a93d5087e3f4b9ca485163c3730e212.png
代码中只启动了两个子进程,但是为什么有3个python进程?这是因为,python会创建一个主进程(第1个进程),当运行到p1.start()时会创建一个子进程(第2个进程),当运行到p2.start()时又会创建一个子进程(第3个进程)
2.进程池
进程的创建和删除是需要消耗计算机资源的,如果有大量任务需要多进程完成,则可能需要频繁的创建删除进程,这会给计算机带来较多的资源消耗。进程池的出现解决了这个问题,它的原理是创建适当的进程放入进程池,等待待处理的事件,当处理完事件后进程不会销毁,仍然在进程池中等待处理其他事件,直到事件全部处理完毕,进程退出。 进程的复用降低了资源的消耗。
实现进程池
import time, os
from multiprocessing import Pool
def worker(msg):
start_time = time.time()
print(F"{msg}开始执行,进程pid为{os.getpid()}")
time.sleep(1)
end_time = time.time()
print(F"{msg}执行完毕,耗时{end_time - start_time}")
def main():
po = Pool(3) # 定义进程池最大进程数为3
for i in range(10):
# 每次循环会用空闲出的子进程调用目标
po.apply_async(worker, args=(i,)) # 若调用的函数报错,进程池中不会打印报错信息
po.close()# 关闭进程池,关闭后,不再接收新的目标
po.join() # 等待进程池中所有子进程执行完,必须放在close()之后。若没有join()操作,主进程执行完后直接关闭
print("--end--")
if __name__ == "__main__":
main()3.线程
在早期的操作系统中并没有线程的概念,进程是拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。后来,随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是就发明了线程,线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID,当前指令指针PC,寄存器和堆栈组成。而进程由内存空间(代码,数据,进程空间,打开的文件)和一个或多个线程组成。
实现多线程
import timeimport threadingdef say(sleep_time): for i in range(5): print(f"说{i+1}下") time.sleep(sleep_time)def dance(): for i in range(10): print(f"跳{i+1}下") time.sleep(1)def main(): # 创建线程对象 # target:指定线程调用的函数名。注:等号后跟方法名不能加括号,如果加了也能执行函数但threading功能无效 # args:指定调用函数时传递的参数。注:args是一个数组变量参数,只传一个参数时,需要在参数后面添加逗号 t1 = threading.Thread(target=say, args=(1,)) t2 = threading.Thread(target=dance) # 启动线程 t1.start() t2.start() # 查看正在运行的线程 while True: now_threading = threading.enumerate() print(now_threading) # 当子线程全部运行结束后,仅剩1个主线程 if len(now_threading)
页:
[1]