主进程如何将客户端连接分配到房间进程
这是一个多进程+多线程的高并发架构,各组件协同工作如下:
系统架构概览
主进程 (main.cpp)
├── 线程池 (userdeal.cpp) // 处理客户端连接请求
└── 进程池 (房间进程, room.cpp) // 管理房间内通信├── 接收线程 (accept_fd) // 接收主进程分配的连接└── 发送线程池 (send_func) // 转发房间内消息
一、线程池(主进程内)
1. 创建与作用
- 位置:
main.cpp
的main()
函数 - 创建代码:
tptr = (Thread *)Calloc(nthreads, sizeof(Thread)); for(i = 0; i < nthreads; i++) {thread_make(i); // 创建线程池 }
- 作用:
- 监听并接受客户端连接(
accept()
) - 解析客户端初始请求(创建/加入房间)
- 不处理具体业务,仅作为"调度器"将连接分配给房间进程
- 监听并接受客户端连接(
2. 工作流程 (userdeal.cpp
)
3. 关键代码 (userdeal.cpp
)
void dowithuser(int connfd) {// 解析请求头部...if(msgtype == CREATE_MEETING) {// 找到空闲房间进程char cmd = 'C';write_fd(room->pptr[i].child_pipefd, &cmd, 1, connfd);close(connfd); // 主进程关闭连接} else if(msgtype == JOIN_MEETING) {char cmd = 'J';write_fd(room->pptr[i].child_pipefd, &cmd, 1, connfd);close(connfd); // 主进程关闭连接}
}
二、进程池(房间进程)
1. 创建与作用
- 位置:
main.cpp
的process_make()
- 创建代码:
for(i = 0; i < nprocesses; i++) {process_make(i, listenfd); // 创建房间进程 }
- 特点:
- 每个进程独立管理一个"房间"
- 进程间完全隔离,避免全局锁竞争
- 通过socketpair与主进程通信
2. 进程内部线程架构
房间进程 (process_main)
├── 接收线程 (accept_fd):1个
│ └── 接收主进程分配的连接
└── 发送线程池 (send_func):多个└── 转发房间内消息
三、关键协作机制
1. 连接传递机制
2. 线程/进程职责对比
组件 | 所属进程 | 数量 | 职责 |
---|---|---|---|
主线程 | 主进程 | 1 | 管理线程/进程池,监听进程状态 |
线程池 | 主进程 | N | 接收连接并分配到房间进程 |
房间进程 | 子进程 | M | 管理独立房间 |
accept_fd线程 | 房间进程 | 1/进程 | 接收主进程分配的连接 |
send_func线程 | 房间进程 | 5/进程 | 转发房间内消息 |
四、资源管理关键点
-
连接生命周期:
- 主进程的线程池
accept()
获取connfd
- 通过
write_fd()
将connfd
传递给房间进程 - 主进程立即关闭
connfd
(房间进程接管)
- 主进程的线程池
-
房间进程状态同步:
// main.cpp的主循环 if(Read(pipefd, &rc, 1) == 'E') {pthread_mutex_lock(&room->lock);room->pptr[i].child_status = 0; // 标记房间空闲room->navail++; }
-
线程安全控制:
- 主进程:
room->lock
保护进程池状态 - 房间进程:
user_pool->lock
保护连接池
- 主进程:
五、设计优势
-
层级分离:
- 连接接收 vs 业务处理
- 房间隔离 vs 进程内并发
-
高效资源利用:
主进程:1监听线程 + N接收线程 房间进程:1连接线程 + 5发送线程 → 总线程数 = 1 + N + M*(1+5)
-
错误隔离:
- 单个房间崩溃不影响其他房间
- 线程崩溃只影响单个房间
六、典型工作流示例
-
用户A创建房间:
- 线程池接收连接 → 分配空闲房间进程 → 房间进程标记A为房主
-
用户B加入房间:
- 线程池接收连接 → 找到目标房间进程 → 房间进程广播B加入
-
房主退出:
- 房间进程检测到房主断开 → 清理房间资源 → 通知主进程房间空闲
这种架构通过三层分配机制(线程池→进程池→线程池)实现高效连接管理和资源隔离,适合高并发会议场景。主进程的线程池专注于连接调度,房间进程内的线程池专注于消息转发,各司其职又通过进程间通信紧密协作。