什么是进程?
程序是静态的,当程序运行起来就叫做进程。是操作系统分配资源的基本单元。
进程、线程的区别与优缺点
定义的不同:
进程是系统进行资源分配的最小单位.
线程是进程的一个实体
,是CPU进行调度的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
区别:
一个程序至少有一个进程,一个进程至少有一个线程.线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程不能够独立执行,必须依存在进程中
进程的创建-multiprocessing
multiprocessing
模块就是跨平台版本(windos和linux)的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情
- 进程的创建步骤
Import multiprocessing # 导入进程模块
# 创建一个进程的实力对象 target=该进程中要执行的函数 args=执行函数中要传入的参数(必须是元组) kwargs=字典参数
P = Multiprocessing.Process(target=func_name[,args=(元组), kwargs={字典}])
p.start() # 创建并启动进程(进程在此处从一个对象变成一个有生命的运行中的程序)
p.join(5) # 等待子进程p运行结束后再执行下面的代码,(5)表示超时时间,等待时间超过5秒将不再等待继续向下执行
代码如下:
import multiprocessing
import time
import os
def test1():
while True: # os模块的getpid()可以获得该进程的进程号,os.ppid()可以获得该进程的父进程的进程号
print("---in 子进程1 PID: %d 父进程PID:%d" % (os.getpid(), os.getppid()))
time.sleep(1)
def test2():
while True:
print("---in 子进程2 PID: %d 父进程PID:%d" % (os.getpid(), os.getppid()))
time.sleep(1)
def main():
p = multiprocessing.Process(target=test1)
p2 = multiprocessing.Process(target=test2)
p2.start()
p.start()
while True:
print("---in 主进程 PID:%d" % os.getpid())
time.sleep(1)
if __name__ == "__main__":
main()
运行结果
---in 主进程 PID:12083
---in 子进程2 PID: 12084 父进程PID:12083
---in 子进程1 PID: 12085 父进程PID:12083
可以看到两个子进程的父进程就是主进程
进程间通信-Queue
Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。
Queue的使用
可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息列队程序,首先用一个小实例来演示一下Queue的工作原理:
from multiprocessing import Queue
q=Queue(3) #初始化一个Queue对象(队列),队列中最多可存入3条消息
q.put("消息1") # put() 加入队列消息
q.put("消息2")
# q.full() 判断队列是否已经满了
print(q.full()) #False
q.put("消息3")
print(q.full()) #True
#因为消息列队已满下面的try都会抛出异常,第一个try会等待2秒后再抛出异常,第二个Try会立刻抛出异常
try:
q.put("消息4",True,2)
except:
print("消息列队已满,现有消息数量:%s"%q.qsize()) # qsize()可以输出队列内信息的个数
try:
q.put_nowait("消息4") # put_nowait() 不等待
except:
print("消息列队已满,现有消息数量:%s"%q.qsize())
#推荐的方式,先判断消息列队是否已满,再写入
if not q.full():
q.put_nowait("消息4")
#读取消息时,先判断消息列队是否为空,再读取
if not q.empty(): # empty()判断队列是否为空
for i in range(q.qsize()):
print(q.get_nowait()) # q.get() 弹出队列的第一个消息,当队列中没有消息时会堵塞, get_nowait()队列中没有消息的时候也不堵塞
进程间不共享全局变量
虽然进程间可以通信,但是不能共享全局变量,因为进程是有生命的,有自己独立的系统资源,就好像两个人,一个人吃饭了,另一个人并不会感觉到饱.