【问题标题】:Shutdown Persistent TCP Con. (C multithreaded server)关闭持久 TCP Con。 (C 多线程服务器)
【发布时间】:2011-07-03 21:49:44
【问题描述】:

我正在设计一个带有线程池的多线程服务器。该系统旨在使用持久的 TCP 连接,因为客户端将保持接近 24/7 的连接。我遇到的问题是如何管理停机。目前,连接通过“accept(listen_fd ....)”进入并分配给工作订单结构。该结构被转储到工作队列中,并被线程拾取。从此时起,该线程专门用于当前连接。我在线程内的代码是:

/* 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 如何创建套接字连接。我问这个,因为如果我对 select 的理解被清除了,也许它适用于我问的问题?

另外,我如何检测连接超时的情况?

谢谢!

编辑 经过进一步的挖掘,我想我可能终于找到了解决方案:

Wake up thread blocked on accept() call

基本上,我可以创建一个全局管道,并让每个线程在其自己的 socket_fd 以及这个全局管道上进行选择。然后,当捕获到信号时,我将向管道写入一些内容。所有线程都应该被唤醒,不是吗?

【问题讨论】:

    标签: sockets pthreads


    【解决方案1】:

    您可以使用recv() 原语。如果返回 0,则表示套接字已关闭。

    更多信息:http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#recvman

    【讨论】:

      【解决方案2】:

      嗯,在 FreeBSD、MacOSX 和其他地方可能有 kevent() 调用,它允许监听广泛的系统事件,包括连接请求和数据到达套接字时的信号。 它将以一种简洁的方式解决您的所有问题,但它不便携。有诸如 libevent 和 libev 之类的库,它们包装了特定于操作系统的功能,例如 BSD 上的 kevent()、Linux 上的 epoll() 等等。或许对你有帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        • 2015-11-17
        • 1970-01-01
        • 2019-04-18
        相关资源
        最近更新 更多