前情回顾
1.epoll模型 : 效率高 , 触发方式更多
2.本地套接字 AF_UNIX 本地两个进程间的消息通信
3.多任务编程
* 并行 和 并发
* 进程 线程
4. 多进程编程
时间片 PCB PID 父子进程 优先级 进程特征
进程状态: 就绪态 运行态 等待态
5. ps -aux ps -ajx pstree top nice
6. os.fork()
7. os.getpid() os.getppid()
os._exit() sys.exit()
8. 孤儿进程和僵尸进程
****************************************************
如何避免僵尸进程产生
* 处理子进程退出状态
pid,status = os.wait()
功能 :在父进程中阻塞等待处理子进程退出
返回值: pid 退出的子进程的PID号
status 获取子进程退出状态
pid,status = os.waitpid(pid,option)
功能 :在父进程中阻塞等待处理子进程退出
参数 : pid -1 表示等待任意子进程退出
>0 表示等待对应PID号的子进程退出
option 0 表示阻塞等待
WNOHANG 表示非阻塞
返回值: pid 退出的子进程的PID号
status 获取子进程退出状态
waitpid(-1,0) ===> wait()
* 让父进程先退出
1. 父进程创建子进程等待子进程退出
2. 子进程创建二级子进程后立即退出
3. 二级子进程称为孤儿,和原来的父进程各自执行 事件
聊天室
功能 : 类似qq群聊
1. 进入聊天室需要输入姓名,姓名不能重复
2. 有人进入聊天室会向其他人发送通知
xxx 进入了聊天室
3. 一个人发消息,其他人会收到消息
xxx 说 : xxxxxxxx
4. 某人退出聊天室,其他人也会收到通知
xxx 退出了聊天室
5. 管理员喊话 服务端发送消息所有的客户端都就收到
管理员说 :xxxxxx
功能模型 : 转发
需要的技术 : 套接字通信 udp套接字
用户存储 : 字典或列表
消息收发的随意性 : 多进程
代码设计
1.封装 将每个功能封装为函数
2.接口测试 (每实现一步就测试一步)
代码编写流程
搭建网络连接 --》 创建多进程---》每个进程功能编写--》项目功能模块实现
进入聊天室
客户端 : 输入姓名 将信息发给服务端(L name)
等待服务端回复 根据回复判断是否登录成功
服务端 : 接收请求信息 判断请求类型
判断用户名是否存在 如果存在回复不能登录
如果不存在回复可以登录并插入到数据结构
发送通知给其他用户
聊天
客户端 : 创建父子进程 发送聊天请求/接收聊天信息
服务端 : 接收请求信息 将消息转发给其他客户端
退出
管理员消息
multiprocessing 模块创建进程
1. 需要将要执行的事情封装为函数
2. 使用multiprocessing模块中Process类创建进程对象
3. 通过对象属性设置和Process的初始化函数对进程进行设置,绑定要执行的函数
4. 启动进程,会自动执行进程绑定的函数
5. 完成进程的回收
Process()
功能 : 创建进程对象
参数 : name 进程名称 Process-1
target 绑定函数
args 元组 给target函数按照位置传参
kwargs 字典 给target函数按照键值对传参
p.start()
功能:启动进程
* target函数会自动执行,此时进程真正被创建
p.join([timeout])
功能 : 阻塞等待回收子进程
参数 : 超时时间
* 使用multiprocessing创建子进程,同样子进程复制父进程的全部代码段,父子进程各自执行互不影响,父子进程有各自的运行空间
* 如果不使用join回收子进程则子进程退出后会成为僵尸进程
* 使用multiprocessing创建子进程往往父进程只是用来创建进程回收进程