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

在多线程TCP服务器中使用Listen()sys调用 我是在Linux下使用BurkelSocket API在系统无关的C语言中进行多线程TCP服务器设计。服务器必须执行I/O多路复用,因为服务器是管理客户机的集中控制器(永远保持与服务器的持久连接(除非运行客户机的机器出现故障等))。服务器需要处理至少500个客户端。 我有一个16核的机器,我想要的是我产生16个线程(每个核心一个)和一个主线程。主线程将listen()连接,然后将队列列表上的每个连接分派给一个线程,该线程将调用accept(),然后使用select()sys调用执行I/O多路复用。现在的问题是,我如何知道何时分派线程调用accept()。我的意思是如何在主线程中发现listen()上有一个挂起的连接,以便我可以分配一个线程来处理该连接。非常感谢大家的帮助。 谢谢。,c,multithreading,sockets,network-programming,C,Multithreading,Sockets,Network Programming,函数调用listen()为接受传入连接准备套接字。然后在该套接字上使用select(),并收到一个新连接已到达的通知。然后在服务器套接字上调用accept,将返回一个新的套接字id。如果愿意,可以将套接字id传递到线程上 我要做的是使用一个线程来接受连接和接收数据,然后将数据作为工作项发送到队列进行处理。epoll或aio/asio。我怀疑您没有收到对先前帖子的回复,因为您在要求提供可扩展的高性能解决方案时没有指定linux。不同操作系统上的异步解决方案都是通过大量的内核支持实现的,linux

函数调用listen()为接受传入连接准备套接字。然后在该套接字上使用select(),并收到一个新连接已到达的通知。然后在服务器套接字上调用accept,将返回一个新的套接字id。如果愿意,可以将套接字id传递到线程上


我要做的是使用一个线程来接受连接和接收数据,然后将数据作为工作项发送到队列进行处理。

epoll或aio/asio。我怀疑您没有收到对先前帖子的回复,因为您在要求提供可扩展的高性能解决方案时没有指定linux。不同操作系统上的异步解决方案都是通过大量的内核支持实现的,linux aio、Windows IOCP等都有很大的不同,以至于“系统独立”并不真正适用——没有人能给你答案


现在您已经将操作系统的范围缩小到linux,请查找相应的异步解决方案。

请注意,如果您的16个线程中的每一个都将运行
select
(或poll,或其他),那么将服务器套接字添加到它们的选择集中是没有问题的

当服务器套接字具有传入连接时,可能会有多个套接字被唤醒,但只有一个会成功调用
accept
,因此它应该可以工作

优点:易于编码

反对:

  • 朴素的实现无法平衡负载(例如需要全局 统计每个线程处理的已接受套接字的数量,包括 高负载线程(从其选择集中删除服务器套接字)
  • 雷鸣般的羊群行为在高接受率下可能会产生问题

非常感谢,这让我的工作轻松了一点。我可以尝试一些平衡负载的方法,但是有什么优雅的方法可以避免雷鸣般的羊群行为吗?如果只有在启动时才会发生accept,例如,启动时有500个客户端和所有请求连接,该怎么办?一旦它们都连接好,每个线程就会在其选择集上执行I/O多路复用?使用这种方法是否足够合适?在这种情况下,只需确保
listen
队列良好且较长,并确定负载平衡。如果总是有东西要接受(直到每个人都连接起来),那么很少有唤醒会被浪费掉。如果一个事件触发多个虚假的唤醒,那么这只是一个雷鸣般的群体——如果有真正的工作可以并行完成,那么这实际上是理想的。