多线程Linux Socket编程设计

时间:2014-08-31 17:56:16

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

我正在尝试编写一个支持一个客户端的服务器程序,直到现在和我试图开发它的几天,我总结说我需要线程。这样决定的原因是因为我从wifi套接字接收输入并稍后处理它并最终写入文件,处理时间很慢,因此我需要一个输入线程 - >循环缓冲区 - >使用生产者消费者模型输出线程模式,这在网络编程中很常见。

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

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

感谢。

2 个答案:

答案 0 :(得分:0)

  

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

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

答案 1 :(得分:-1)

一些意见和建议。

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