C++ 多端口的多线程?

C++ 多端口的多线程?,c++,networking,boost,network-programming,C++,Networking,Boost,Network Programming,首先,我对网络编程了解不多 因此,我有一个程序(进程),需要监听3个端口。。。两个是TCP,另一个是UDP 这两个TCP端口将每隔一段时间接收大量数据(可能是每5分钟或每20秒接收一次)。第三个(UDP)端口正在接收常量数据。现在,让这些线程监听不同的线程有意义吗 例如,当我从一个TCP端口接收到大量数据时,我不希望我的UDP流被中断。。。这些是网络编程的常见问题吗 谢谢大家。。。如果我不清楚,请随时提出澄清问题 我将在Windows上使用Boost库,如果这有任何意义的话 编辑:再读一遍后,我

首先,我对网络编程了解不多

因此,我有一个程序(进程),需要监听3个端口。。。两个是TCP,另一个是UDP

这两个TCP端口将每隔一段时间接收大量数据(可能是每5分钟或每20秒接收一次)。第三个(UDP)端口正在接收常量数据。现在,让这些线程监听不同的线程有意义吗

例如,当我从一个TCP端口接收到大量数据时,我不希望我的UDP流被中断。。。这些是网络编程的常见问题吗

谢谢大家。。。如果我不清楚,请随时提出澄清问题

我将在Windows上使用Boost库,如果这有任何意义的话


编辑:再读一遍后,我意识到我不是在问一个特定的问题,哈哈。。。我想我只是在寻找一些关于这个问题的想法/想法/指导,以及如何管理多个连接。感谢使用线程,每个接收连接一个线程,将有助于保持高吞吐量,并防止一个端口的数据阻塞另一个端口的处理

这是一个好主意,尤其是因为你说的只有3个连接。生成三个线程来处理通信将使您的应用程序更易于维护和保持性能。

首先

…这些是网络编程的常见问题吗

是的,线程问题是网络编程中非常常见的问题

第二,使用三个线程在三个不同端口上侦听的设计思想是可行的,允许您同时在所有三个端口上侦听。正如评论中指出的,这不是唯一的方法


最后,网络编程中常见的一种设计是让一个线程侦听连接,然后生成一个新的助手线程来处理连接。原始侦听器线程只是将套接字连接传递给助手,然后直接返回侦听新连接。

通常,除非必要,否则避免线程。在现代机器上,通过使用单个线程和I/O就绪/完成功能,您将获得更好的性能。在Windows上,这是IO完成端口,在Mac OS X和FreeBSD:kqueue(2)上,在Solaris:Event端口上,在Linux e波尔上,在VMS QIO上。等等

在boost中,这是由boost::asio抽象的


线程非常有用的地方是,您必须执行重要的处理或执行阻塞操作系统调用,这会给其余的网络处理增加不可接受的延迟。

多个线程不能扩展。在数千或上万个连接的规模上,操作系统线程的重量太重了。当然,你只有3个,所以没什么大不了的。事实上,如果您确信您的应用程序不需要扩展,我甚至可能以简单的名义向您推荐它

但在scale中,您可能希望使用
select()/poll()/epoll()/libevent/etc
。在现代Linux系统上,epoll()是迄今为止最健壮、速度最快的。一个线程同时轮询所有套接字上的套接字就绪情况,然后发出就绪信号的套接字要么由单个线程立即处理,要么更频繁地被传递到线程池。线程池具有有限数量的线程(通常是本地计算机上可用的计算内核数量的一部分),其中每当套接字就绪时,就会抓取一个空闲线程

同样,每个连接可以使用一个线程,但是如果您对学习构建可伸缩网络系统的正确方法感兴趣,请不要这样做。构建select()/poll()样式的服务器是一次非常棒的学习体验

有关参考信息,请参阅C10K问题:


这是错误的。如果你试图用一个线程来处理多个套接字,那么你的性能会很差。胡说八道!随着套接字数量的增加,如果每个套接字有一个线程,那么性能将显著下降。这种架构有很多例子,包括大多数现代web服务器。对于较旧的、众所周知的检查,请参阅:您是否确实尝试过放大这些内容?您不需要多个线程来侦听不同的端口。使用select()或等效项等待所有侦听套接字上的输入事件。select()是否来自Boost?如果没有,你能给我指一下这个函数的文档吗,这样我就可以找到一个boost equiv了?谢谢,Karunskisect来自您的操作系统。在boost中,请参阅asio库,该库在其实现中使用select(如果适用)。select是原始BSD套接字API的一部分,在类似Windows和Unix的操作系统中实现。检查MSDN或手册页。asio是围绕select()和其他等效异步IO API的跨平台抽象。它可以扩展到4或5个连接。。。最多6个吧。这个应用程序在使用上相当具体。谢谢你的提示!我建议您遵循“boost:asio/select/Windows完成端口API”和“线程池”答案之一的建议(并将其标记为正确)。请注意,对于您的应用程序,每个端口执行一个线程是最简单的实现。虽然你可能会说今天你永远不会需要超过4-6个插座,但有一天你可能需要这个应用程序扩展到更多的插座。因此,今天使用线程池可能会为你自己(或跟随你的人)省去很多麻烦。每个人似乎都认为您想要构建一个web服务器。我不知道答案(这就是为什么这只是一个注释),但我怀疑如果UDP流是高吞吐量的,并且您希望避免丢弃UDP数据包,那么您真的希望它能够在不同的处理器上运行。