一个正在运行的程序或者软件就是一个进程
主进程就像是一个集团,集团下面有很多子公司(子进程),集团本身也是一个公司,每个公司真正干活的是不同岗位的员工(线程/多线程)
multi_process.py
import multiprocessing
import time
def listen_music():
for i in range(3):
print('听音乐......','进程名:%s'%multiprocessing.current_process().name)
time.sleep(0.2)
def read_book():
for i in range(3):
print('看书......','进程名:%s'%multiprocessing.current_process().name)
time.sleep(0.2)
if __name__ == '__main__':
# 创建听音乐进程(子进程)
listen_music_process = multiprocessing.Process(target=listen_music,name='我是听音乐的进程')
# 创建看书进程 (子进程)
read_book_process = multiprocessing.Process(target=read_book,name='我是看书的进程')
# 启动子进程
listen_music_process.start()
read_book_process.start()
运行结果
听音乐...... 进程名:我是听音乐的进程
看书...... 进程名:我是看书的进程
听音乐...... 进程名:我是听音乐的进程
看书...... 进程名:我是看书的进程
听音乐...... 进程名:我是听音乐的进程
看书...... 进程名:我是看书的进程
Process 继承于 BaseProcess
class BaseProcess(object):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={},
*, daemon=None):
参数说明:
常??法:
import os
os.getpid() 表示获取当前进程编号
os.getppid() 表示获取当前父进程编号
获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是由那个主进程创建出来的
multi_process_id.py
import multiprocessing
import time
import os
def listen_music():
# 获取当前进程的编号
print('listen_music 进程当前编号:',os.getpid())
# 获取当父进程的编号
print('listen_music 父程当前编号:',os.getppid())
for i in range(3):
print('听音乐......','进程名:%s'%multiprocessing.current_process().name)
time.sleep(0.2)
def read_book():
# 获取当前进程的编号
print('read_book 进程当前编号:', os.getpid())
# 获取当父进程的编号
print('read_book 父进程当前编号:', os.getppid())
for i in range(3):
print('看书......','进程名:%s'%multiprocessing.current_process().name)
time.sleep(0.2)
if __name__ == '__main__':
# 获取当前进程的编号
print("主进程 main 编号:", os.getpid())
# 创建听音乐进程(子进程)
listen_music_process = multiprocessing.Process(target=listen_music,name='我是听音乐的进程')
# 创建看书进程 (子进程)
read_book_process = multiprocessing.Process(target=read_book,name='我是看书的进程')
# 启动子进程
listen_music_process.start()
read_book_process.start()
运行结果
主进程 main 编号: 2281
listen_music 进程当前编号: 2283
listen_music 父程当前编号: 2281
听音乐...... 进程名:我是听音乐的进程
read_book 进程当前编号: 2284
read_book 父进程当前编号: 2281
看书...... 进程名:我是看书的进程
听音乐...... 进程名:我是听音乐的进程
看书...... 进程名:我是看书的进程
听音乐...... 进程名:我是听音乐的进程
看书...... 进程名:我是看书的进程
multi_process_args.py
import multiprocess
import time
def task(task_name):
for i in range(3):
print('我的任务名:',task_name)
time.sleep(0.2)
if __name__ == '__main__':
# 任务一:听歌
task1 = multiprocessing.Process(target=task,args=('听歌...',))
# 任务二:看书
task2 = multiprocessing.Process(target=task,kwargs={'task_name':'看书...'})
# 启动任务
task1.start()
task2.start()
运行结果
我的任务名: 听歌...
我的任务名: 看书...
我的任务名: 听歌...
我的任务名: 看书...
我的任务名: 看书...
我的任务名: 听歌..
创建子进程会对主进程资源进行拷贝,也就是说子进程是主进程的一个副本,之所以进程之间不共享全局变量,是因为操作的不是同一个进程里面的全局变量,只不过不同进程里面的全局变量名字相同而已。
multi_process_global_var.py
import multiprocessing
import os
MY_LIST = []
def task(task_name):
print(task_name, '的父进程id:', os.getppid())
for i in range(3):
print(i, task_name, '的进程id', os.getpid())
MY_LIST.append(i)
print(task_name, ',MY_LIST:', MY_LIST)
if __name__ == '__main__':
print('主进程id:', os.getppid())
task1 = multiprocessing.Process(target=task, args=('task1',))
task2 = multiprocessing.Process(target=task, args=('task2',))
task1.start()
task2.start()
task1.join()
task2.join()
print('主进程 MY_LIST', MY_LIST)
运行结果
主进程id: 14628
task2 的父进程id: 1976
0 task2 的进程id 17040
1 task2 的进程id 17040
2 task2 的进程id 17040
task2 ,MY_LIST: [0, 1, 2]
task1 的父进程id: 1976
0 task1 的进程id 16436
1 task1 的进程id 16436
2 task1 的进程id 16436
task1 ,MY_LIST: [0, 1, 2]
主进程 MY_LIST []
孤儿进程
正常情况下,主进程会等待所有的子进程执行结束再结束,但是如果主进程突然被Kill,剩下的进程就叫做"孤儿进程"
僵尸进程
如果子进程在exit()之后,父进程没有来得及处理,那么保留的那段信息就不会释放,其进程号就会一直被占用, 这种进程称为“僵尸进程”
Process类 run 方法
如果没有给定target参数,对这个对象调?start()?法时,就将执
?对象中的run()?法
multi_process_run
import os
from multiprocessing import Process
class MyMultiProcess(Process):
def __init__(self, task_name):
Process.__init__(self)
self.task_name = task_name
def run(self):
for i in range(3):
print(i, self.task_name, '的进程id', os.getpid(),'---','父进程id:',os.getppid())
if __name__ == '__main__':
print('父进程id:', os.getpid())
p1 = MyMultiProcess('task1')
p2 = MyMultiProcess('task2')
p1.start()
p2.start()
运行结果
父进程id: 15292
0 task1 的进程id 6596 --- 父进程id: 15292
0 task2 的进程id 12540 --- 父进程id: 15292
1 task1 的进程id 6596 --- 父进程id: 15292
1 task2 的进程id 12540 --- 父进程id: 15292
2 task1 的进程id 6596 --- 父进程id: 15292
2 task2 的进程id 12540 --- 父进程id: 15292
进程池用于快速大量生成进程任务,把所有进程任务添加到进程池,进程池有一个同时执行的最大进程数,当任务数量多余设置的最大进程数,那么后面的任务会进入等待,任务先进先出。
multi_process_pool
from multiprocessing import Pool
import os
def task(task_name):
for i in range(3):
print(task_name, '的进程id', os.getpid(), '---', '父进程id:', os.getppid())
if __name__ == '__main__':
# 定义?个进程池,最?进程数2
process_pool = Pool(2)
# 往进程添加任务
for i in range(3):
# 非堵塞的方式添加任务
process_pool.apply_async(func=task,args=('任务%s'%(i+1),))
# 关闭进程池 , 关闭后不再添加新的任务
process_pool.close()
process_pool.join()
运行结果
任务1 的进程id 8624 --- 父进程id: 6372
任务2 的进程id 17188 --- 父进程id: 6372
任务1 的进程id 8624 --- 父进程id: 6372
任务2 的进程id 17188 --- 父进程id: 6372
任务1 的进程id 8624 --- 父进程id: 6372
任务2 的进程id 17188 --- 父进程id: 6372
任务3 的进程id 8624 --- 父进程id: 6372
任务3 的进程id 8624 --- 父进程id: 6372
任务3 的进程id 8624 --- 父进程id: 6372
Pool常?方法:
multiprocessing 模块的 Queue 类实现多进程之间的数据传递
‘‘‘
‘‘‘
原文:https://www.cnblogs.com/snailrunning/p/12169209.html