2017-08-10 97 views
0

考虑通过tcp套接字将200个检测器连接到程序的情况。他们非常频繁地发送他们的数据,并且我想尽可能有效地处理它。从多个tcp连接读取数据

我可以考虑2种方法来解决这个问题,但我在QT方面很新,所以我不知道哪一个更好。

  1. 创建将运行从QRunnable()衍生的200个对象线程池,每个对象将包括一个插座和槽将被连接到该插座的信号,使关于一个检测器的所有数据将被处理在那一个对象中。 (在run()方法中会有QEventLoop)

  2. 创建200个对象,每个对象将由套接字组成,并将这200个套接字信号连接到主线程中的一个插槽。所以它将在一个插槽中处理来自200个检测器的数据。

哪种方法会更好consdering,在第一种方法会出现创建200个QEventLoops(每个对象)的事实呢?

+0

好的旧'poll()'/'epoll()'有什么问题?你不需要一堆线程来处理类似的事情。 –

+0

Research'select()'函数。它旨在使单线程可以监视多个输入通道。还有一些东西需要研究:函数调用比线程上下文切换快大约1000倍。 –

+0

据我所知,Qt在QEventLoop的后台使用select()(事件循环处于休眠状态,直到内核事件发送给应用程序),那么我的第二种方法有什么问题?如果我错了,请纠正我。 – notfound404

回答

0

有没有必要直接到epoll。例如,你可以使用像uvw这样专用的东西。

+0

在我看来,如果他打算使用第三方网络API,那么显而易见的将是Qt API的网络组件,他已经在使用其他的东西。否则,他增加了一个额外的依赖项,没有明显的补偿收益。 –

+0

如果建议直接使用epoll(),那么第三方网络库的优势显而易见:便携性和易用性。但是,如果Qt性能可以接受,那么他们是明显的选择。不过,他必须避免200个线程。 – Praise

0

我认为任何解决方案都可以工作,但我绝对推荐避免每个连接线程的解决方案,因为200个线程大约198个线程太多,并且效率不高。

我会这样做的方式是创建一个线程并在该线程内运行select()(或poll()或epoll()或其他)事件循环来处理那里的200个TCP连接,使用非阻塞I/O。当数据到达该线程时,该线程可以将数据解析为合适的数据块,然后通过Queued信号/槽连接(或qApp-> postEvent()if)将解析/组合数据发送到主线程(如果需要)你更喜欢这样做)。 (在单独的线程中进行联网有助于防止GUI操作干扰网络性能,反之亦然)反之亦然

在网络线程中创建〜200个QTCPSocket对象(并使网络线程运行Qt标准QEventLoop处理它们)也可能工作得很好;上一次我试图说我遇到了Qt在某些平台上实现网络的一些性能问题,但这又回到了Qt4的时代,所以我对Qt从那时起提高了它的实现效率感到乐观。

+0

谢谢你的回答,但是我从来没有建议使用~200线程,而是使用QThreadPool和默认的maxThreadCount()设置为QThread :: idealThreadCount(),但我现在看到了这个解决方案的弱点。 我想我会在一个线程中创建所有套接字并将它们的信号连接到一个插槽,之后我将利用QThread中QEventLoop的优势来处理套接字事件。我希望它会有效率。 – notfound404

0

在所有情况下,您不需要比逻辑处理器内核更多的线程。在线程中分配对象。使用旋转事件回调的QRunnable是毫无意义的,即使我承认在某人的请求中以回答的方式展示它。 Eventloops也不便宜 - 每个都需要几千字节的堆栈,至少在我的平台上。因此,最好使用QThread,每个线程有一个单一的eventloop,然后以循环方式在线程之间分配网络对象。