2012-01-30 47 views
1

我正在使用Berkely SOCKET API在系统无关的C语言中使用Berkely SOCKET API进行多线程TCP服务器设计。服务器必须执行I/O多路复用,因为服务器是一个集中控制器,用于管理客户端(永久保持与服务器的永久连接(除非客户端运行的计算机失败等))。服务器需要处理至少500个客户端。 我有一个16核心机器,我想要的是我产生了16个线程(每个核心一个)和一个主线程。主线程将listen()连接到连接,然后将队列列表中的每个连接分派给一个线程,然后该线程将调用accept(),然后使用sys调用执行I/O复用。现在的问题是我怎么知道什么时候派遣一个线程来致电accept()。我的意思是我如何在主线程中发现在listen()处挂起一个连接,以便我可以分配一个线程来处理该连接。所有帮助非常感谢。 谢谢。在多线程TCP服务器中使用Listen()sys调用

回答

1

请注意,如果16个线程中的每一个线程都将运行select(或轮询,或其他任何方法),那么它们全都将服务器套接字添加到其选择集中并没有问题。

服务器插座有进入连接时可能会唤醒多个,但只有一个会成功调用accept,所以它应该工作。

专业:易于编码。

缺点:

  • 天真实现不均衡负载(需要如由每个线程处理接受的套接字的数量全球 统计,与 高负荷线从他们中选择删除服务器插槽。套)
  • 雷鸣般的羊群行为可能是有问题的高接受率
+0

非常感谢,让我的工作变得更轻松。我可以尝试一些措施来平衡负荷,但是会有什么优雅的方式来避免雷鸣般的羊群行为?什么如果有一种情况是只在开始时接受,例如在启动时有500个客户端和所有的请求连接?一旦它们全部连接并且每个线程在其选择集上执行I/O复用?这将是一个足够体面的方案来使用这种方法吗? – Abdullah 2012-01-30 14:22:18

+0

在这种情况下,只要确保'listen'队列很好并且很长,并找出负载均衡。如果总有一些东西需要“接受”(直到每个人都连接起来),那么很少的唤醒就会被浪费掉。如果单个事件触发多次虚假唤醒,那么这只是一个雷鸣般的群体 - 如果真的有可以并行完成的工作,那实际上是理想的。 – Useless 2012-01-30 14:28:36

+0

非常感谢您的解释。干杯:) – Abdullah 2012-01-30 16:22:42

2

listen()函数调用准备套接字来接受传入连接。然后,您使用该套接字上的select()并获取新连接已到达的通知。然后在服务器套接字上调用accept,并返回一个新的套接字标识。如果你喜欢,你可以将该套接字标识传递给你的线程。

我会做的是有一个线程接受连接和接收数据,然后将数据分派到队列作为处理工作项。

0

epoll或aio/asio。我怀疑你没有回复你之前的文章,因为当你要求一个可扩展的高性能解决方案时你没有指定linux。不同操作系统上的异步解决方案通过大量的内核支持和linux aio,Windows IOCP等实现不同,“独立于系统”并不适用 - 没有人可以给你一个答案。

既然您已经将操作系统缩小到Linux,请查找相应的异步解决方案。

+0

感谢。我的坏,我没有指定操作系统。非常感激。 – Abdullah 2012-01-30 14:04:11