Reading data from multiple tcp connection

2019-08-23 14:09发布

问题:

Consider situation where you have 200 detectors that are connected to your program through tcp sockets. They are quite frequently sending their data and I would like to handle it as efficiently as possible.

I can think of 2 approaches for this problem, but I'm quite new in QT so I don't know which one is better, if any.

  1. Create a threadpool that will be running 200 objects derived from QRunnable(), each object will consist of a socket and slots that will be connected to this socket signals, so that all data concerning one detector will be handled in that one object. (In it's run() method there will be QEventLoop)

  2. Create 200 objects, each object will consist of socket and connect those 200 socket signals to one slot in the main thread. So It will handle data from 200 detectors in one slot.

Which approach would be better consdering the fact that in the first approach there will be created 200 QEventLoops (for each object)?

回答1:

There is no need to get down to epoll directly. You could use something dedicated like uvw, for example.



回答2:

I think any solution can work, although I definitely recommend avoiding a thread-per-connection solution, as 200 threads is about 198 threads too many and would not be very efficient.

The way I would do it is to create one thread and run a select() (or poll() or epoll() or whatever) event loop inside that thread to handle the 200 TCP connections there, using non-blocking I/O. When data arrives in that thread, that thread can parse the data into the appropriate chunks and then send the parsed/assembled data on to the main thread (if necessary) via a Queued signal/slot connection (or qApp->postEvent() if you prefer doing it that way). (Doing the networking in a separate thread would help prevent GUI actions from interfering with network performance, and vice-versa)

Creating ~200 QTCPSocket objects in the network thread (and having the network thread run the Qt-standard QEventLoop to handle them) would also probably work well; the last time I tried that I ran into some performance issues with Qt's implementation of networking on some platforms, but that was back in the Qt4 days so I'm optimistic that Qt has improved their implementation's efficiency since then.



回答3:

In all cases, you don't want more threads than there are logical processor cores. Distribute the objects across the threads. Using a QRunnable that spins an eventloop is fairly pointless, even if I admit to demonstrating it in a SO answer on someone's request. Eventloops aren't cheap either - each takes a few kilobytes of stack, at least on my platform. Thus it's better to just use QThread that has a single eventloop per thread, and then distribute the network objects across the threads in a round-robin fashion.