- 创建进程的多种方式
- join方法
- 进程间数据隔离
- 进程间通信(IPC机制)
- 生产者与消费者模型
- 进程相关方法
- 守护进程
- 僵尸进程与孤儿进程
- 双击桌面程序图标
- 代码创建程序
- 使用Process创建进程
from multiprocessing import Process def task(name): print(f'{name}正在运行') if __name__ == '__main__': p = Process(target=task, args=('task',)) # 创建一个进程对象 p.start() # 启动一个进程(异步操作) print('主进程') # 由于是异步操作,在操作系统启动进程时这里已经打印完毕,所以子进程内容最后打印
- 使用类创建进程
from multiprocessing import Process class MyProcess(Process): def __init__(self, name): super().__init__() self.name = name def run(self): print('子进程运行') if __name__ == '__main__': obj = MyProcess('jason') obj.start() print('主进程')
创建进程的代码在不同的操作系统中底层原理有区别
在windows中,创建进程类似于导入模块,所以需要__name__ == __main__来防止出现无限循环
在mac、Linux中,创建进程类似与将代码拷贝一份
- 使用Process创建进程
join:使主进程阻塞,在子进程运行结束后在运行
import time from multiprocessing import Process def task(n): print('子进程开始') time.sleep(n) print('子进程结束') if __name__ == '__main__': p = Process(target=task, args=(5,)) p.start() p.join() # 等待p子进程运行结束后继续向下执行 print('主进程') """需要注意join的执行位置""" if __name__ == '__main__': p1 = Process(target=task, args=(5,)) p2 = Process(target=task, args=(4,)) p3 = Process(target=task, args=(3,)) p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() print('主进程') """这段代码相当于同步阻塞,每次执行子代码都会等待""" if __name__ == '__main__': p1 = Process(target=task, args=(5,)) p2 = Process(target=task, args=(4,)) p3 = Process(target=task, args=(3,)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print('主进程') """相当于异步非阻塞,只需要等待五秒多"""进程间数据隔离
多个进程之间的数据默认是相互隔离的,如果需要在进程之间交互,需要借助’管道’或’队列’
from multiprocessing import Process num = 100 def task(): global num num = 200 if __name__ == '__main__': p = Process(target=task) p.start() print(num) # 子进程修改的是自身的num,影响不到主进程进程间通信(IPC)
队列:先进先出
from multiprocessing import Queue q = Queue(3) # 创建队列对象,括号内指定队列可以存放的数据数量,默认为2147483647 q.put(111) # 往队列里添加数据 q.put(222) q.put(333) q.full() # 判断队列是否为满 # q.put(444) # 如果队列已经存满了,继续向队列里存放数据程序会阻塞,直到队列有数据被取出 q.get() # 从队列中获取数据 q.get() q.get() q.empty() # 判断队列是否为空 # q.get() # 如果队列已经空了,继续从队列里获取数据程序会阻塞,直到队列中有数据被存入 q.get_nowait() # 从队列中获取数据,如果队列为空,直接报错 """ q.full() q.empty() q.get_nowait 这几个方法在多进程中不能够准确使用 """
IPC(InterProcess Communication)机制
- 主进程与子进程通信
- 子进程与子进程通信
from multiprocessing import Process, Queue def task1(q): print('task1>>>:', q.get()) q.put('task1') def task2(q): print('task2>>>:', q.get()) if __name__ == '__main__': q = Queue(5) q.put('主进程') p1 = Process(target=task1, args=(q,)) p2 = Process(target=task2, args=(q,)) p1.start() p1.join() p2.start()生产者与消费者模型
完整的生产者消费者模型至少有三个部分
生产者:产生数据
缓冲区:存放数据
消费者:处理数据
1.查看进程号 from multiprocessing import current_process current_process().pid # 获取当前程序进程号 import os os.getpid() # 获取当前程序进程号 os.getppid() # 获取当前程序父程序的进程号 2.销毁子进程 process.terminate() from multiprocessing import Process import time def task(): print('task') time.sleep(1) print('task') if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() # 结束子进程 3.判断进程是否存活 p.is_alive()守护进程
守护进程会随着被守护进程的结束而结束
import time from multiprocessing import Process def task(): while True: # 当主进程结束时,守护进程也结束 print('task') time.sleep(1) if __name__ == '__main__': p = Process(target=task) p.daemon = True # 设置为守护进程,必须在程序启动前设置 p.start() print('主程序睡眠') time.sleep(5) print('主程序结束')僵尸进程与孤儿进程
僵尸进程:进程已经结束运行,但是相关的资源并没有完全清空,需要父进程参与回收;
孤儿进程:父进程异常结束,子进程正常运行,就被称作孤儿进程,孤儿进程会被操作系统接管
server:
import socket from multiprocessing import Process def task(sk): msg = sk.recv(1024).decode('utf8') sk.send(msg.upper().encode('utf8')) if __name__ == '__main__': server = socket.socket() server.bind(('127.0.0.1', 8081)) server.listen(5) while True: sock, address = server.accept() p = Process(target=task, args=(sock,)) p.start()
client:
import socket client = socket.socket() client.connect(('127.0.0.1', 8081)) data = input('>>>:').strip() client.send(data.encode('utf8')) print(client.recv(1024).decode('utf8'))