【问题标题】:Multi threaded Linux Socket programming design多线程 Linux Socket 编程设计
【发布时间】:2014-10-25 00:37:24
【问题描述】:

到目前为止,我正在尝试编写一个支持一个客户端的服务器程序,在我尝试开发它的几天里,我得出结论我需要线程。做出这样决定的原因是因为我从 wifi 套接字获取输入,然后对其进行处理,最后写入文件,处理时间很慢,因此我需要一个输入线程 -> 循环缓冲区 -> 输出线程模式与生产者消费者在网络编程中很常见的模型。

现在,情况变得复杂了,因为我需要管理客户端断开连接和重新连接。我想过使用 pthread_exit() 并清理所有信号量,然后在每次单个客户端重新连接时重新初始化它们。

我的问题是这是一种有效的方法,即每次都杀死线程和信号量并重新创建它们。有没有更好的解决方案。

谢谢。

【问题讨论】:

    标签: multithreading sockets network-programming pthreads producer-consumer


    【解决方案1】:

    我的问题是这是一种有效的方法,即每次都杀死线程和信号量并重新创建它们。有没有更好的解决方案。

    1. 了解如何使用非阻塞套接字和事件循环。或者使用为您提供 TCP 会话的库,使用引擎盖下的非阻塞套接字。如boost::asio
    2. 通过使用消息传递在线程之间进行通信,而不是共享状态,了解如何使用多线程而不用任何同步原语污染您的代码。您用于非阻塞 I/O 的事件循环库也应该提供跨线程消息传递的方法。

    【讨论】:

      【解决方案2】:

      一些cmets和建议。

      1-在 TCP 中检测到对方已经悄悄地断开连接,即使不是不可能,也非常困难。客户端可以断开向服务器发送 RST TCP 消息或发送 FIN 消息,这是很好的情况。有时客户端可以在没有通知的情况下断开连接(崩溃、电缆断开等)。

      • 这里的一个建议是您考虑客户端和服务器的通信方式。例如,您可以使用“select”函数设置接收客户端消息的超时时间并检测静默客户端。

      • 此外,根据编程语言和操作系统,您可能需要处理损坏的管道 (SIGPIPE) 信号(在 Linux 中,使用 C/C++),以便服务器尝试通过关闭的连接发送消息客户。

      2-关于信号量,当客户端断开连接时,您不需要以任何特殊方式清理信号量。通过应用锁定和解锁互斥锁的常见良好实践就足够了。同样对于文件描述符等资源,您需要在结束线程之前通过从线程启动函数返回或使用 pthread_exit 来释放它们。可能我没看懂这部分问题。

      3-关于线程:如果您使用多个线程以达到最佳效果,那么您将拥有一个预先创建的消费者/工作线程池,这些线程将检查循环缓冲区以使用下一个可用连接。创建和销毁线程对操作系统来说代价高昂。

      • 线程消耗资源,例如,如果您需要创建 1,000 个线程,您可能会耗尽操作系统资源。

      • 另一种选择是只有一个消费者线程异步管理所有连接(套接字): a) 每个连接都有自己的状态。 b) 主线程遍历所有连接并使用函数“select”来检测连接读取或写入何时准备好。 3)使用非阻塞套接字,但这不是必需的,因为从选择中您知道哪些套接字已准备好并且不会阻塞。

      • 您可以使用函数 select、poll、epoll。

      关于选择和非阻塞套接字的一个链接:Using select() for non-blocking sockets 其他示例链接:http://linux.die.net/man/2/select

      【讨论】:

      • 编辑后,我使用简单的标志来指示线程停止并最终加入。它适用于两个连接,第三个连接面临问题。我应该在关闭前一个套接字和新套接字时延迟一些吗?
      • 在为新连接创建任何新套接字 fd 之前,我将关闭所有描述符。
      • 你不是在使用标准的socket函数,比如bind、listen、accept等吗?您粘贴的代码对我来说没有多大意义。
      猜你喜欢
      • 2012-06-28
      • 1970-01-01
      • 2013-04-18
      • 2017-04-29
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多