了解进程(Process)
对于进程的定义,从不同的角度可以有不同的定义
- 进程是程序的一次执行
- 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
- 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配合调度的一个独立单位
程序是指令、数据及其组织形式的描述,进程是程序的实体。
进程是进程实体的运行过程,系统进行资源分配合调度的一个独立单位。
举例说明:
程序:例如 xxx.py
这是程序,是一个静态的。
进程:一个程序运行起来后,代码 用到的资源称之为进程,它是操作系统分配资源的独立单位。
进程的状态
工作中,任务数往往大于 CPU 的核数,即一定有一些任务正在执行,而另外一些任务在等待 CPU 进行执行,因此导致了有了不同的状态
- 就绪态:运行的条件都已经慢去,正在等在 CPU 执行
- 执行态: CPU 正在执行其功能
- 等待态:等待某些条件满足,例如一个程序 sleep 了,此时就处于等待态
Python多进程
GIL(Global Interpreter Lock 全局解释器锁):每个线程在执行的过程中都需要先获取 GIL
,保证同一时刻只有一个线程可以执行代码。
由于 GIL(全局解释器锁) 的原因,Python中的多线程是 “伪并行” 无法利用 CPU
多核优势,如果想要充分地使用多核 CPU
的资源,在Python中大部分情况需要使用多进程。Python提供了 multiprocessing
模块来实现多进程。
multiprocessing 创建多进程
multiprocessing
模块就是跨平台版本的多进程模块,提供了一个 Process
类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。
2个while循环一起执行
代码语言:javascript复制# -*- coding:utf-8 -*-
import time
from multiprocessing import Process # 首先导入Process类
def run_proc():
"""子进程要执行的代码"""
while True:
print("----2----")
time.sleep(1)
if __name__=='__main__':
p = Process(target=run_proc) # 传入要执行的目标函数
p.start() # 启动进程
while True:
print("----1----")
time.sleep(1)
运行结果如下:
代码语言:javascript复制----1----
----2----
----1----
----2----
----1----
----2----
----1----
----2----
----1----
----2----
...
说明
- 创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用 start() 方法启动
Process语法结构
代码语言:javascript复制Process([group [, target [, name [, args [, kwargs]]]]])
参数 | 含义 |
---|---|
target | 表示调用对象,即子进程要执行的任务 |
args | 给target指定的函数传递的参数,以元组的方式传递 如:args=(1, 2, ‘hui’, ) |
kwargs | 给target指定的函数传递关键字参数 如:kwargs={‘name’: ‘hui’, ‘age’: 18} |
name | 给进程设定一个名字,可以不设定 |
group | 指定进程组 |
Process对象的常用方法
方法 | 作用 |
---|---|
start() | 启动子进程实例(创建子进程) |
is_alive() | 判断进程子进程是否还在活着 |
join([timeout]) | 是否等待子进程执行结束,或等待多少秒 |
terminate() | 不管任务是否完成,立即终止子进程 |
Process对象的常用属性
name
:当前进程的别名,默认为Process-N
,N为从1开始递增的整数pid
:当前进程的pid(进程号)
给子进程指定的函数传递参数
代码语言:javascript复制# -*- coding:utf-8 -*-
import os
from time import sleep
from multiprocessing import Process
def run_proc(name, age, **kwargs):
for i in range(10):
print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
print(kwargs)
sleep(0.2)
def main():
p = Process(target=run_proc, args=('test',18), kwargs={"m":20})
p.start()
sleep(1) # 1秒中之后,立即结束子进程
p.terminate() # 终止子进程
p.join()
if __name__=='__main__':
main()
运行结果:
代码语言:javascript复制子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
继承Process类创建多进程
创建进程的方式还可以使用类的方式,可以自定义一个类,继承 Process 类,重写run方法,每次实例化这个类的时候,就等同于实例化一个进程对象
代码语言:javascript复制import time
from multiprocessing import Process
# 定义进程类
class ClockProcess(Process):
def __init__(self,interval):
super().__init__(self) # 记得加载Process类的__init__()方法
self.interval = interval
def run(self):
print('子进程开始执行的时间:{}'.format(time.ctime()))
time.sleep(self.interval)
print('子进程结束的时间:{}'.format(time.ctime()))
def main():
# 创建子进程睡眠两秒
p = ClockProcess(2)
# 调用子进程
p.start()
# 等待子进程结束
p.join()
print('主进程结束')
if __name__=='__main__':
main()
运行结果
代码语言:javascript复制子进程开始执行的时间:Sat Oct 3 23:21:20 2020
子进程结束的时间:Sat Oct 3 23:21:22 2020
主进程结束
继承 Process 类,重写run方法,实例化的对象调用 start()
方法就会执行 run()
方法的代码
进程间不共享全局变量
代码语言:javascript复制# -*- coding:utf-8 -*-
import os
import time
from multiprocessing import Process
nums = [11, 22]
def work1():
"""子进程要执行的代码"""
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
for i in range(3):
nums.append(i)
time.sleep(1)
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
def work2():
"""子进程要执行的代码"""
print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
def main():
p1 = Process(target=work1)
p1.start() # 子进程开启
p1.join() # 等待子进程执行结束
p2 = Process(target=work2)
p2.start()
if __name__ == '__main__':
main()
运行结果:
代码语言:javascript复制in process1 pid=11349 ,nums=[11, 22]
in process1 pid=11349 ,nums=[11, 22, 0]
in process1 pid=11349 ,nums=[11, 22, 0, 1]
in process1 pid=11349 ,nums=[11, 22, 0, 1, 2]
in process2 pid=11350 ,nums=[11, 22]
说明: p1
进程往 num
列表添加的元素,与 p2
进程不共享,p2
进程打印的还是原来的 num[11, 12]
。
Python多线程、进程对比
对比方式 | 线程 | 进程 |
---|---|---|
Python模块 | threading | multiprocessing |
开启方式 | threading.Thread() 继承 Thread 类 | multiprocessing.Process() 继承 Process 类 |
共享全局变量 | 共享 | 不共享 |
公众号
新建文件夹X
大自然用数百亿年创造出我们现实世界,而程序员用几百年创造出一个完全不同的虚拟世界。我们用键盘敲出一砖一瓦,用大脑构建一切。人们把1000视为权威,我们反其道行之,捍卫1024的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。