原理叙述
并发服务器从框架结构上分为以下四个步骤:
- 建立TCP socket服务器
- 编译一个解析HTTP request的解析器
- 后续处理
- 产生response
并发服务器要求高并发,在linux环境下可用epoll多路IO服用机制,程序内部使用线程池,若需使用队列或者hash表等容器,可使用intel的tbb开源c++计算库
- epoll多路复用机制较select与poll相比,没有并发连接数量的限制,并且呢效率提升,而不是select的无差别轮询,在内存拷贝方面,利用mmap函数避免了内存与内核数据复制
- 线程池实现多个线程并行处理,也可以直接用多线程thread实现
- 在多线程环境中,公共存储需要加锁,不然会造成资源冲突,但是加锁较耗费时间,用的最多的锁有互斥锁、读写锁、自旋锁,tbb的c++并行计算库实现了无锁队列以及hash表。
大致流程图
关键代码实现
int startServer(int port) {
HttpServer http_server;
//http_server.set_thread_pool(&tp);
init_facetable(faceTable);
cout<<"face table size startServer: "<<faceTable.size()<<endl;
http_server.add_mapping("/api/face/login", login, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/add", faceAdd, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/identify", faceIdentify, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/setName", faceSetName, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/list", faceList, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/remove", faceRemove, GET_METHOD | POST_METHOD);
http_server.add_mapping("/api/face/query", query, GET_METHOD | POST_METHOD);
//http_server.add_mapping("/api/download/face_image", faceimageDownload, GET_METHOD | POST_METHOD);
// http_server.add_bind_ip("127.0.0.1");
http_server.set_port(port);
http_server.set_backlog(10000);
http_server.set_max_events(10000);
//http_server.add_bind_ip("192.168.238.158");
http_server.start_async();
//sleep(1);
//http_server.stop();
http_server.join();
http_server.stop();
return 0;
}