1、进程
1.1 程序与进程
进程:是系统进行资源分配的基本单位
进程:动态的概念,运行起来的程序,包括程序,以及运行程序所需要的计算机资源等
程序:静态的概念,我们写的 .py .go 等,都是程序
1.2 多进程的概念
import multiprocessing
import os
num = 0
def add_num1():
global num
for i in range(1000000):
num += 1
print('子进程1已经完成,此时得到的num',num,'当前子进程编号',os.getpid(),'当前子进程父进程编号(主进程)',os.getppid())
def add_num2():
global num
for i in range(1000000):
num += 1
print('子进程2已经完成,此时得到的num',num)
if __name__ == '__main__':
print('主进程编号',os.getpid())
# print(os.getppid())
process1 = multiprocessing.Process(target=add_num1)
process2 = multiprocessing.Process(target=add_num2)
process1.start()
process2.start()
展示:
主进程编号 3468
子进程2已经完成,此时得到的num 1000000
子进程1已经完成,此时得到的num 1000000 当前子进程编号 11588 当前子进程父进程编号(主进程) 3468
注意点:
1、os.getpid()获取执行当前任务的进程编号
2、os.getppid()获取的是当前进程的父进程编号
3、多进程之间不共享全局变量,多个进程之间是独立的
1.3传参
def add_num1(count):
global num
for i in range(count):
num += 1
print('子进程1已经完成,此时得到的num',num,'当前子进程编号',os.getpid(),'当前子进程父进程编号(主进程)',os.getppid())
# process1 = multiprocessing.Process(target=add_num1,args=(100,))
# 关键字传参
process1 = multiprocessing.Process(target=add_num1, kwargs={'count':100})
1.4 队列
from multiprocessing import Queue
que = Queue(3)
try:
for i in range(4):
que.put('123',True,1)
except Exception as e:
print('消息队列已经满了,当前数据有%s个'%que.qsize())
展示:
消息队列已经满了,当前数据有3个
注意点:
1、put在默认情况下,如果队列已经满了,一直阻塞,等待队列出现空余位置
2、如果设置了timeout,那么等待过后,会报错
3、block设置为False,直接报错
#if not que.full():
# for i in range(que.qsize()):
# que.put_nowait('123')
def readData(que):
if not que.empty():
data = que.get_nowait()
print(data)
def writeData(que):
if not que.full():
try:
que.put_nowait('123')
except:
pass
if __name__ == '__main__':
q = Queue(5)
p1 = Process(target=writeData,args=(q,))
p2 = Process(target=readData,args=(q,))
import time
p1.start()
time.sleep(5)
p2.start()
展示:
123
1.5 进程池
from multiprocessing import Pool
import os
import time
def info():
print('执行该函数的进程编号',os.getpid())
time.sleep(0.1)
print('这是一个函数')
if __name__ == '__main__':
po = Pool(3)
print(po)
for i in range(10):
po.apply_async(info)
print('####开始###')
# 将进程池关闭,不再接收新的请求
po.close()
# 等待进程池中的进程全部结束
po.join()
print('####结束###')
展示:
<multiprocessing.pool.Pool object at 0x05A0EA10>
####开始###
执行该函数的进程编号 11020
执行该函数的进程编号 6884
执行该函数的进程编号 11384
这是一个函数
执行该函数的进程编号 11020
这是一个函数
执行该函数的进程编号 6884
这是一个函数
执行该函数的进程编号 11384
这是一个函数
执行该函数的进程编号 11020
这是一个函数
执行该函数的进程编号 6884
这是一个函数
执行该函数的进程编号 11384
这是一个函数
执行该函数的进程编号 11020
这是一个函数
这是一个函数
这是一个函数
####结束###
1.6 进程与线程的区别
1、线程是进程中的一个实例,真正干活的人是线程,
2、进程只是资源分配的基本单位,线程是调度的基本单位
3、没有进程就没有线程这个概念
4、不同的进程一起运行,其中一个进程死了,其他进程不受影响
5、在同一个进程内,如果线程消亡,那这个进程受影响,所以从健壮性来讲,进程比线程更加稳定
6、线程共享全局变量,进程创建子进程相当于粘贴复制,此时相当于创建了一份副本,不共享全局变量