目录线程池Thread PoolI/O 复用I/O Multiplexing协程Coroutine一、线程池C实现思路核心结构示例代码简化线程池特点二、I/O 复用select / epoll示例多连接监听特点三、协程C语言模拟版本协程思想核心示例状态机版协程特点四、三者对比C实现视角五、最重要的系统级理解线程池Thread Pool解决如何高效管理“任务执行线程”预先创建线程任务来了就分配避免频繁创建/销毁线程适合CPU任务 / 业务处理I/O 复用I/O MultiplexingI/O复用解决一个线程如何管理多个连接用 select / epoll 监听多个 socket哪个有事件就处理哪个不阻塞等待协程Coroutine解决一个线程如何执行多个“可暂停任务”用户态调度遇到 IO 自动挂起恢复时继续执行适合高并发 IO如爬虫、服务端一、线程池C实现思路核心结构任务队列queueworker线程固定数量互斥锁 条件变量示例代码简化线程池#include pthread.h #include stdio.h #include stdlib.h #include unistd.h #define THREAD_NUM 3 #define TASK_NUM 10 typedef struct { int task_id; } task_t; task_t task_queue[TASK_NUM]; int task_count 0; pthread_mutex_t mutex; pthread_cond_t cond; void* worker(void* arg) { int id *(int*)arg; while (1) { pthread_mutex_lock(mutex); while (task_count 0) { pthread_cond_wait(cond, mutex); } task_t task task_queue[--task_count]; pthread_mutex_unlock(mutex); printf(线程 %d 处理任务 %d\n, id, task.task_id); sleep(1); } return NULL; } int main() { pthread_t threads[THREAD_NUM]; int ids[THREAD_NUM]; pthread_mutex_init(mutex, NULL); pthread_cond_init(cond, NULL); for (int i 0; i THREAD_NUM; i) { ids[i] i; pthread_create(threads[i], NULL, worker, ids[i]); } // 投递任务 for (int i 0; i TASK_NUM; i) { pthread_mutex_lock(mutex); task_queue[task_count].task_id i; pthread_mutex_unlock(mutex); pthread_cond_signal(cond); } sleep(10); return 0; }特点多线程并行线程复用适合 CPU/业务任务二、I/O 复用select / epollI/O复用这里用select版本最经典示例多连接监听#include stdio.h #include string.h #include unistd.h #include sys/select.h #include sys/socket.h #include arpa/inet.h int main() { int server_fd socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; addr.sin_family AF_INET; addr.sin_addr.s_addr INADDR_ANY; addr.sin_port htons(8080); bind(server_fd, (struct sockaddr*)addr, sizeof(addr)); listen(server_fd, 5); fd_set readfds; int max_fd server_fd; while (1) { FD_ZERO(readfds); FD_SET(server_fd, readfds); int ret select(max_fd 1, readfds, NULL, NULL, NULL); if (FD_ISSET(server_fd, readfds)) { int client_fd accept(server_fd, NULL, NULL); printf(新连接%d\n, client_fd); } } return 0; }特点单线程管理多个连接事件触发处理避免线程爆炸三、协程C语言模拟版本C语言没有原生协程但可以用setjmp / longjmp状态机或 ucontext已废弃但经典协程思想核心“函数可以暂停下次从上次位置继续”示例状态机版协程#include stdio.h typedef struct { int state; } coroutine_t; void task(coroutine_t* co) { switch (co-state) { case 0: printf(任务开始\n); co-state 1; return; case 1: printf(处理中...\n); co-state 2; return; case 2: printf(任务结束\n); co-state -1; return; } } int main() { coroutine_t co {0}; while (co.state ! -1) { task(co); } return 0; }特点单线程手动保存状态模拟“挂起/恢复”本质是用户态调度四、三者对比C实现视角模型核心机制是否多线程是否阻塞适用场景线程池pthread是可能阻塞CPU任务I/O复用select/epoll否不阻塞网络服务器协程状态机模拟否非阻塞高并发IO五、最重要的系统级理解一个现代服务器通常是epollI/O复用 线程池 协程思想例如nginxepoll 事件驱动redis单线程 IO复用Go runtime协程调度器