Skip to content

进程

  • 进程是指在系统中正在运行的一个应用程序,是 CPU 的最小工作单元。
  • python 通过multiprocessing模块管理进程的

优点

  • 进程之间的内存是独立的,一个进程的崩溃不会影响到其他进程。
  • 进程可以并发执行,每个进程都有自己的寄存器和栈,进程的执行顺序是由操作系统的进程调度器来控制的。

缺点

  • 进程的创建和销毁需要消耗更多的资源。
  • 进程之间的通信需要通过进程间通信(IPC)机制来实现,比较复杂。

任务堵塞

  • 任务堵塞是指任务执行时间较长,导致其他任务无法执行。
  • 任务堵塞的原因是进程的执行顺序是由操作系统的进程调度器来控制的,进程调度器会根据进程的优先级、时间片等因素来决定进程的执行顺序。
python
import time

def task1():
	while True:
		time.sleep(1)
		print("task1...........")

def task2():
	while True:
		time.sleep(1)
		print("task2...........")

if __name__ == '__main__':
    # task2会一直等待task1执行,因为task1是一个死循环,不会结束,所以不会执行task2。
	task1()
	task2()

Process

  • 基于multiprocessing模块 Process类管理进程
    • target:指定要执行的任务函数。
    • name:指定进程的名称。
    • args:指定任务函数的参数。
    • kwargs:指定任务函数的关键字参数。
    • daemon:指定进程是否为守护进程。

常用函数

  • is_alive():进程是否还在运行。
  • start():启动子进程,并执行任务函数。
  • run():执行任务函数,不会开启子进程。
  • join():等待进程结束,不然主进程会提前结束。
  • terminate():终止进程。

进程管理

python
import os
import time
from multiprocessing import Process

def task1(s, msg):
	while True:
		time.sleep(s)
		print("task1....", msg, "进程id:", os.getpid(), "父进程id:", os.getppid())

def task2(s, msg):
	while True:
		time.sleep(s)
		print("task2....", msg, "进程id:", os.getpid(), "父进程id:", os.getppid())

if __name__ == '__main__':
	p1 = Process(target = task1, name = 'p1', args = (1, "hello"))  # 把任务1 命名为p1
	p2 = Process(target = task2, name = 'p2', args = (1, "world"))  # 把任务2 命名为p2
	p1.start()  # 启动进程并执行任务1
    p1.join()   # 等待进程p1执行完毕,不然主进程会提前结束
	p2.start()  # 启动进程并执行任务2
    p2.join()   # 等待进程p2执行完毕,不然主进程会提前结束

    # p1.run()  # 直接执行任务1,不启动进程
    # p2.run()  # 直接执行任务2,不启动进程

    p1.terminate()  # 终止进程p1
    p2.terminate()  # 终止进程p2

Pool

  • Pool类指定一个最大进程数,当请求来时,如果池子没满,则新增进程,否则等待进程池中的进程执行完毕。
  • 基于multiprocessing模块 Pool类管理进程池
    • processes:指定进程池的大小。
    • initializer:指定进程池的初始化函数。
    • initargs:指定进程池的初始化函数的参数。

常用函数

  • close():表示添加进程结束。
  • join():等待进程池中的进程执行完毕,防止主进程提前结束。
  • terminate():立即终止进程池中的所有进程。
  • apply():阻塞模式,等待进程池中的进程执行完毕。
  • apply_async():非阻塞模式,不等待进程池中的进程执行完毕。
  • map():阻塞模式,等待进程池中的进程执行完毕。
  • map_async():非阻塞模式,不等待进程池中的进程执行完毕。

非阻塞模式

  • apply_async():非阻塞模式,不等待进程池中的进程执行完毕。
python
import os
import time
from multiprocessing import Pool

def task1(s, name):
	while True:
		time.sleep(s)
		print('task 1', name, str(os.getppid()) + "_" + str(os.getpid()))

def task2(s, name):
	while True:
		time.sleep(s)
		print('task 1', name, str(os.getppid()) + "_" + str(os.getpid()))

if __name__ == '__main__':
	pool = Pool(5)
	# 非阻塞模式
	pool.apply_async(task1, args = (1, 'task1'))
	pool.apply_async(task2, args = (1, 'task2'))
	pool.close() # 表示添加进程结束
	pool.join()  # 等待进程池中的进程执行完毕,防止主进程提前结束

阻塞模式

  • apply():阻塞模式,等待进程池中的进程执行完毕。
python
import os
import time
from multiprocessing import Pool

num = 1

def task1(s, name):
	while True:
		global num
		if num > 3:
			break
		num = num + 1
		time.sleep(s)
		print('task 1', name, str(os.getppid()) + "_" + str(os.getpid()))

def task2(s, name):
	while True:
		global num
		if num > 3:
			break
		num = num + 1
		time.sleep(s)
		print('task 2', name, str(os.getppid()) + "_" + str(os.getpid()))

if __name__ == '__main__':
	pool = Pool(5)
	# 非阻塞模式
	pool.apply(task1, args = (1, 'task1'))
	pool.apply(task2, args = (1, 'task2'))
	pool.close() # 表示添加进程结束

进程通信

  • 进程通信的方式有:
    • Queue:队列
    • Pipe:管道
    • Manager:管理器

Queue

  • Queue类基于multiprocessing模块 Queue类管理队列
    • maxsize:指定队列的大小。
    • put():向队列中添加元素。
    • get():从队列中获取元素,这个方法是阻塞的,如果没有获取元素,会一直等待。
    • empty():判断队列是否为空。
    • full():判断队列是否已满。
python
from queue import Queue

q = Queue(5)
for i in range(1, 6):
	q.put(i)
print(q.full())     # True
q.maxsize = 10
print(q.full())     # False
print(q.empty())    # False
print(q.get())      # 1
print(q.get())      # 2
print(q.get())      # 3

适应场景

  • 计算密集型任务,如游戏伤害结算,人工智能训练。

注意事项

  • 各个进程的变量是独立的,互不干扰。