进程是操作系统进行资源分配和调度的一个基本单位。
在Python中,可以通过multiprocessing模块开启多个进程来帮我们同时执行多任务。
例如,xxx.py运行起来后,至少会开启一个进程,这个进程叫主进程,如果我们要同时执行多任务,我们可以开启多个进程来执行多任务,这些进程叫子进程。
既有主进程,又有子进程,这时候就是多进程。每个进程中可以执行一个或多个任务,这样就实现了多任务。
补充:
并发:指的是任务数多于CPU核数,通过操作系统的各种任务调度算法,实现多个任务“一起”执行(实际上,同一时间只有一个任务在执行,操作系统是通过时间片轮询的方式,轮流让各个任务交替执行。
例如:任务1执行0.0001秒,切换到任务2,任务2执行0.0001秒,再切换到任务3,执行0.0001秒,又切换回任务1……这样循环下去。因为切换任务的速度相当快,我们感觉就像所有任务都在同时执行一样。)
并行:当任务数小于或者等于CPU核数时,每一个任务都有对应的CPU来处理执行,即任务真的是一起执行的(实际上,我们的电脑上运行的任务数量非常多,除了我们开启的任务,还有很多任务在后台运行着,而CPU数量是有限的,基本上不可能一个任务占一核CPU。由于任务数量远远多于CPU的核心数量,所以,操作系统会自动把很多任务轮流调度到每个核心上执行。)
from multiprocessing import Process import time def coding(language): """子进程要执行的代码""" for i in range(5): print("{} coding".format(language), end=' | ') time.sleep(1) if __name__ == '__main__': # 单进程 start = time.time() coding('python') for i in range(5): print("main program", end=' | ') time.sleep(1) end = time.time() print('\nOne process cost time:', end - start) # 多进程 multi_start = time.time() p = Process(target=coding, args=('python', )) p.start() for i in range(5): print("main program", end=' | ') time.sleep(1) multi_end = time.time() print('\nMulti process cost time:', multi_end - multi_start)
运行结果:
python coding | python coding | python coding | python coding | python coding | main program | main program | main program | main program | main program |
One process cost time: 10.004231691360474
main program | python coding | main program | python coding | main program | python coding | main program | python coding | main program | python coding |
Multi process cost time: 5.082065582275391
multiprocessing模块是跨平台和版本的多进程模块,提供了一个Process类来创建进程对象。创建子进程时,只需要传入一个需要执行的函数和函数的参数,创建一个Process实例,用start()方法启动这个实例。
在上面的代码中,定义了一个coding函数,实现多进程时,实例化了一个Process类的对象p,p就是一个进程对象,将需要执行的函数传给target参数,将coding函数需要的参数以元组的形式传给args参数(必须是一个元组),再用p对象的start()方法开启了一个子进程。
coding函数是一个需要执行的任务,在主进程中需要执行的代码是另一个任务,这时候有两个任务。两个任务都在主进程中执行时,花了10秒多的时间,创建一个子进程来执行coding函数时,花了5秒多的时间。创建子进程之后,主进程和子进程同时处理任务,这说明我们实现了多进程处理多任务,即多个任务是“同时”执行的。
Process([group [, target [, name [, args [, kwargs]]]]])
Process的常用方法:
Process的常用属性:
获取当前进程的id和当前进程的父进程的id,需要使用os模块:
from multiprocessing import Process import time str_list = ['ppp', 'yyy'] def add_str1(): """子进程1""" print('In process one: ', str_list) for x in 'thon': str_list.append(x * 3) time.sleep(1) print('In process one: ', str_list) def add_str2(): """子进程1""" print('In process two: ', str_list) for x in 'thon': str_list.append(x) time.sleep(1) print('In process two: ', str_list) if __name__ == '__main__': p1 = Process(target=add_str1) p1.start() p2 = Process(target=add_str2) p2.start()
运行结果:
In process one: ['ppp', 'yyy']
In process two: ['ppp', 'yyy']
In process one: ['ppp', 'yyy', 'ttt']
In process two: ['ppp', 'yyy', 't']
In process one: ['ppp', 'yyy', 'ttt', 'hhh']
In process two: ['ppp', 'yyy', 't', 'h']
In process one: ['ppp', 'yyy', 'ttt', 'hhh', 'ooo']
In process two: ['ppp', 'yyy', 't', 'h', 'o']
In process one: ['ppp', 'yyy', 'ttt', 'hhh', 'ooo', 'nnn']
In process two: ['ppp', 'yyy', 't', 'h', 'o', 'n']
在上面的代码中,str_list是一个全局变量,进程p1和p2同时在使用str_list,都在往列表中添加元素,但是两个进程对列表的添加互不相关。
进程p1与进程p2不共享全局变量。
以上为个人经验,希望对您有所帮助。