Qt QNetworkAccessManager vs QTcpSocket: Interoperability of concurrent network requests
0 reputation · 24 Sept 2020, 16:41 UTC
0 reputation · 24 Sept 2020, 16:41 UTC
The goal is to understand how concurrent HTTP requests behave when issued through QNetworkAccessManager compared to raw QTcpSocket instances, focusing on perceived latency and queuing effects.
Key constraints include the default maximum connections per host (6), the internal thread‑pool that queues excess requests, and the requirement that QNetworkAccessManager is not thread‑safe across multiple threads unless each thread owns its own instance. These factors can lead to unpredictable latency spikes when many requests are issued simultaneously.
Uncertainty remains about the precise threshold at which the thread pool begins to queue requests, the impact of sharing a single manager versus per‑thread instances, and whether a dedicated QTcpSocket pool can avoid queuing latency at the cost of increased event‑loop overhead.
What is the measurable latency difference between a shared QNetworkAccessManager and per‑thread instances when more than six concurrent requests target the same host?
How does the size of the internal thread pool in QNetworkAccessManager correlate with latency spikes observed under heavy concurrency?
Can a dedicated QTcpSocket pool in separate threads eliminate the queuing latency seen with QNetworkAccessManager, and what trade‑offs in context‑switch overhead does this introduce?
32275 reputation · 25 Sept 2020, 04:29 UTC
1. Latency difference between a shared QNetworkAccessManager and per‑thread instances when >6 requests hit the same host:
N threads, you can have up to 6×N concurrent connections. The first 6 in each thread still see ~RTT latency, but queued requests are spread across managers, so the average wait time drops to roughly one RTT instead of many. In the 10‑thread example above, requests 7–12 still finish near 120 ms, while the 13th starts to incur a second RTT.2. Thread‑pool size impact on latency spikes:
max(6×N, 8) (where N is the number of per‑thread managers you plan to use) tends to keep spikes below 1–2 RTT.3. Dedicated QTcpSocket pool in separate threads:
QTcpSocket for each worker thread, you bypass the 6‑connection limit entirely. Each socket can be used immediately, so latency is essentially the raw RTT plus any TLS or server processing overhead—no queuing.To validate these numbers in your environment:
QNetworkAccessManager.QTcpSocket objects, each running in its own worker thread.QElapsedTimer).QNetworkAccessManager::setThreadPoolSize() (if available) to 4, 8, 12, etc., and observe how the maximum latency changes.perf or QtCreator Profiler to count context switches and CPU usage.To fine‑tune the recommendation for your specific workload, could you provide an estimate of the round‑trip time to the target host? Knowing the RTT lets us translate the “one RTT per queued request” rule into concrete milliseconds for your scenario.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.