我正在设计一个带线程池的多线程服务器。该系统旨在使用持久性TCP连接,因为客户端将维护24/7接近的连接。我碰到的问题是如何管理关机。目前,一个连接通过“accept(listen_fd ....)”进入,并被分配给工作订单结构。这个结构被转储到工作队列中,并被一个线程拾取。从这一点开始,这个线程专门用于当前的连接。我的线程里面的代码是:关闭持续TCP Con。 (C多线程服务器)
/* Function which runs in a thread to handle a request */
void *
handle_req(void *in)
{
ssize_t n;
char read;
/* Convert the input to a workorder_ptr */
workorder_t *workorder_ptr = (workorder_t *)in;
while(!serv_shutdown
&& (n=recv(workorder_ptr->sock_fd,&read,1,0) != 0))
{
printf("Read a character: %c\n",read);
}
printf("Peer has shutdown.\n");
/* Free the workorder memory */
close(workorder_ptr->sock_fd);
free(workorder_ptr);
return NULL;
}
它只是监听套接字并无限期回声的特点,并且操作正确时,客户机将终止连接。您会在while循环中看到“!serv_shutdown”部分 - 这是我试图让线程在关闭信号上突破其循环。当一个SIGINT被捕获时,全局变量被设置为1.不幸的是,程序当前在recv语句中被阻塞,并且直到另一个字符被读取时才会检查该标志。我想避免这种情况,因为在此连接上发送另一个字符之前可能需要一段任意时间。
此外,我在另一篇文章上看到,最好使用“select”而不是“accept”来等待套接字连接,但我不太明白。你会选择等待,然后在那之后做一个接受吗?我不确定select如何创建套接字连接。我问这个,因为如果我对select的理解被清除了,也许它适用于我所问的问题?
此外,如何检测连接超时的情况?
谢谢!
编辑 我想我可能终于找到了解决办法,经过进一步的挖掘:
Wake up thread blocked on accept() call
基本上,我可以创建一个全球性的管道,并让每个线程做一个选择对自己socket_fd以及这个全球管道。然后,当一个信号被捕获时,我只会写一些东西给管道。所有线程都应该醒来,不是?