一个简单的 Linux 多进程 HTTP 服务器,采用 Daemon + Listener + Manager + Worker 四层进程模型。
+------------------------+
| Daemon Process |
| (监控 & 管理所有进程) |
+------------------------+
| | |
+---------+ 监控 | 监控 +---------+
| 重启 | 重启 |
+----------------+ | | | +------------------+
| Listener Proc | | | | | Manager Proc |
| (accept TCP | ------+ | +------ | (管理 Worker 池 |
| 连接) | | | & 分发连接) |
+----------------+ | +------------------+
| | |
listener_to_manager 按需创建 分发 fd 给
(fd 单向传递) Worker 进程 Worker
(fork+exec)
|
+------------------------+
| Worker Process (Pool) |
| (HTTP 请求处理) |
+------------------------+
|
worker_heartbeat
(所有 Worker 共享,
向 Manager 上报
连接数)
WebServer/
├── CMakeLists.txt
├── Common/ ← 公共库:链表、fd 传递、事件通知
├── Daemon_Main/ ← 守护主进程
│ ├── daemon_main.c
│ ├── structs/ ← 全局 socketpair 声明
│ └── functions/ ← create_worker / listener_monitor / manager_monitor
├── Listener/ ← 端口监听进程
│ ├── listener_main.c
│ ├── structs/ ← fd_queue
│ └── functions/ ← listen_port / send_to_manager
├── Manager/ ← 工作进程池管理
│ ├── manager_main.c
│ ├── structs/ ← socketinfo_queue / WorkerInfo / WorkerPool
│ └── functions/ ← recv_from_listener / worker_heartbeat / recv_new_worker / dispatch
└── Worker/ ← HTTP 工作进程
├── worker_main.c
├── structs/ ← tcpinfo / tcpqueue / tcppool
└── functions/ ← recv_from_manager / tcppool_manage / work_thread / done_handler
所有通道均由 Daemon 在启动时创建,在 fork 子进程前通过 fd_send 将对应端传给目标进程。通道本身归 Daemon 所有,子进程崩溃后无需重建,直接复用。
| socketpair 名称 | 方向 | 用途 |
|---|---|---|
daemon_listener |
双向 | Daemon ↔ Listener 心跳 / 关闭控制 |
daemon_manager |
双向 | Daemon ↔ Manager 心跳 / 关闭控制 |
listener_to_manager |
Listener → Manager | Listener 向 Manager 单向传递客户端 fd |
worker_heartbeat |
所有 Worker → Manager | 全部 Worker 共享写端,向 Manager 上报心跳与连接数(SOCK_DGRAM 保证原子写) |
worker_notification |
Daemon → Manager | Daemon 向 Manager 通知新 Worker 的 task_sock |
create_worker_request |
Manager → Daemon | Manager 向 Daemon 请求创建新 Worker |
客户端 TCP 连接
│
▼
[Listener]
ListenPortThread: accept() → accept_queue
│
SendToManagerThread: fd_send(listener_to_manager)
│
▼
[Manager]
RecvFromListenerThread: fd_recv() → wait_queue
│
DispatchThread: 最少连接策略 → fd_send(task_sock)
│ 若无可用 Worker → create_worker_request → Daemon
│
▼
[Daemon]
CreateWorkerThread: fork+exec Worker
│ fd_send(task_sock via worker_notification)
│
▼
[Manager]
RecvNewWorkerThread: fd_recv(task_sock) → 等待注册(module=30) → 加入 WorkerPool
│
▼
[Worker]
RecvFromManagerThread: fd_recv(task_sock) → accept_queue
│
TcpPoolManageThread: 无数据→入连接池等 epoll,有数据→入 work_queue
│
WorkThread: 解析 HTTP → 响应(GET/404/501)→ done_queue
│
DoneHandlerThread:
├─ keep-alive → 重置 timeout → 重入 accept_queue
└─ close → Destroy_tcpinfo
+-----------------------+
| Daemon Process |
+-----------------------+
|
+----------------------+----------------------+
| | |
+------------------+ +--------------------+ +--------------------+
| ListenerMonitor | | ManagerMonitor | | CreateWorkerThread |
| Thread | | Thread | | |
| 心跳监控 Listener| | 心跳监控 Manager | | 监听创建请求 |
| 超时 → 重启 | | 超时 → 杀所有 | | → fork+exec Worker |
| | | Worker → 重启 | | |
+------------------+ +--------------------+ +--------------------+
ListenPortThread
bind + listen → accept(client_socket) → enqueue(accept_queue)
│
accept_queue
│
SendToManagerThread
dequeue → fd_send(listener_to_manager) → close(本地副本)
RecvFromListenerThread ──→ wait_queue ──→ DispatchThread
│
fd_send(task_sock)
│
WorkerHeartbeatThread ──→ 更新 WorkerPool ▼
(接收心跳,清理死亡 Worker) [Worker 进程]
RecvNewWorkerThread ←── worker_notification ←── [Daemon]
(等注册消息 → 加入 WorkerPool)
RecvFromManagerThread → accept_queue
│
TcpPoolManageThread
├─ 新连接有数据 → work_queue
├─ 新连接无数据 → tcppool(等 epoll)
├─ epoll 触发 → work_queue
└─ 每秒 timeout-- → 超时 → Destroy
│
WorkThread × N → done_queue
│
DoneHandlerThread
├─ keep-alive → 重入 accept_queue
└─ close → Destroy_tcpinfo
各模块详细文档见对应子目录的 README.md。