我有一个app(服务器),它使用accept()从手机(客户端)接收TCP套接字连接。它似乎工作,但当我在Apple Instruments中运行我的应用程序时,我可以看到这个应用程序使用大约100%的CPU,主要原因95%的帐户调用非阻塞accept()。我想我已经添加了这个非阻塞的accept()方法调用,以便能够通过单击GUI按钮“停止服务器”随时停止服务器。通过这个解决方案我可以每次检查我是否有一个标志shouldShutDown等于true然后我关闭服务器()
这是服务器循环的代码:
/**
* Function is looping infinitely and waiting
* for new incoming connections.
* It handles each connection on thread pool's worker thread
*/
result_t thread_pool_stream_server_loop(server_info_t *server_info, connection_handler_t conn_handler) {
sock_fd_t cs_fd, ps_fd;
thread_pool_t *thread_pool;
// get passive server socket
ps_fd = server_info_sock(server_info);
// initialize thread pool and set its size
thread_pool_init(&thread_pool, 5, 10, 3000 /* [ms] */);
while(1) {
if(server_info_should_shut_down(server_info)) {
thread_pool_shutdown(thread_pool);
return CLOSED;
}
if(server_info_force_shut_down(server_info)) {
thread_pool_shutdown(thread_pool);
return FORCE_CLOSED;
}
// check to accept new connections on the main thread...
cs_fd = accept_new_connection(ps_fd);
if(cs_fd == FAILURE) {
fprintf(stderr, "accept_new_connection: failed!\n");
server_info_connection_error_event(server_info, cs_fd, CONN_ERROR_ACCEPT, "accept_new_connection: failed!");
break;
} else if(cs_fd == CONTINUE) {
continue;
}
// publish client connected event
server_info_client_connected_event(server_info, cs_fd);
// revert connection socket to non-blocking
int opts = fcntl(cs_fd, F_GETFL);
opts = opts & (~O_NONBLOCK);
fcntl(cs_fd, F_SETFL, opts);
// handle new connection by thread pool's worker thread
conn_thread_runner_attr_t *connection_thread_runner_attr;
conn_thread_runner_attr_init(&connection_thread_runner_attr);
conn_thread_runner_attr_fill(connection_thread_runner_attr, conn_handler, server_info, cs_fd, NULL, NULL);
thread_pool_run(thread_pool, (runner_t) connection_thread_runner, (runner_attr_t) connection_thread_runner_attr, NULL);
// adjust thread pool actual size to number of added connection handling tasks
thread_pool_adjust_size(thread_pool);
}
thread_pool_force_free(thread_pool);
return FAILURE;
}
答案 0 :(得分:0)
代码正在忙着等待,accept()
返回的内容与EAGAIN
/ EWOULDBLOCK
不同,那么还有什么能比你预期的CPU周期更快?
您可以在拨打select()
之前拨打accept()
,超时10毫秒来解决此问题。