Qt C++ 是静态 thread_local QNetworkAccessManager 线程应用程序的好选择吗?
Qt C++ Is static thread_local QNetworkAccessManager good choice for threaded application?
我正在使用用 Qt (C++) 编写的线程应用程序。
我需要经常从不同的线程发出 get/post 请求。
Qt 文档说:
One QNetworkAccessManager instance should be enough for the whole Qt
application. Since QNetworkAccessManager is based on QObject, it can
only be used from the thread it belongs to.
static thread_local QNetworkAccessManager
对我来说是个不错的选择吗?
不,不是一个好的选择。
您不应该创建静态或全局 QObject
子类实例,因为您通常需要在 创建 Qt 应用程序对象后 创建它们(很多Qt 的东西取决于已经存在的应用程序对象)。 C++ 并没有真正提供对何时实际创建静态对象的很好的控制,而在这里你希望拥有该控制。
只需使用指针和 new
创建 QNetworkAccessManager
实例,数量不限。您可以直接在正确的线程中创建它们,或者您可以在其他(通常是主)线程中创建它们并将它们移动到正确的线程。
为了正确销毁它们,当它们没有自然父代时(因为父代必须存在于同一个线程中!),连接它们线程的 QThread::finished
signal to the objects QObject::deleteLater
插槽,它们将被彻底删除当线程完成时。
如果你想要一个使用当前线程的 QNAM 实例的普通函数,你可以使用线程局部静态 pointer。像
static thread_local *thread_qnam;
void myfunc() {
if (!thread_qnam) {
thread_qnam = new QNetworkAccessManager;
connect(QThread::currentThread, &QThread::finished(), thread_qnam, &QObject::deleteLater);
// Whatever other setup you need.
// It'd probably be good idea to wrap this in a function.
}
// Use thread_qnam...
}
我正在使用用 Qt (C++) 编写的线程应用程序。
我需要经常从不同的线程发出 get/post 请求。
Qt 文档说:
One QNetworkAccessManager instance should be enough for the whole Qt application. Since QNetworkAccessManager is based on QObject, it can only be used from the thread it belongs to.
static thread_local QNetworkAccessManager
对我来说是个不错的选择吗?
不,不是一个好的选择。
您不应该创建静态或全局 QObject
子类实例,因为您通常需要在 创建 Qt 应用程序对象后 创建它们(很多Qt 的东西取决于已经存在的应用程序对象)。 C++ 并没有真正提供对何时实际创建静态对象的很好的控制,而在这里你希望拥有该控制。
只需使用指针和 new
创建 QNetworkAccessManager
实例,数量不限。您可以直接在正确的线程中创建它们,或者您可以在其他(通常是主)线程中创建它们并将它们移动到正确的线程。
为了正确销毁它们,当它们没有自然父代时(因为父代必须存在于同一个线程中!),连接它们线程的 QThread::finished
signal to the objects QObject::deleteLater
插槽,它们将被彻底删除当线程完成时。
如果你想要一个使用当前线程的 QNAM 实例的普通函数,你可以使用线程局部静态 pointer。像
static thread_local *thread_qnam;
void myfunc() {
if (!thread_qnam) {
thread_qnam = new QNetworkAccessManager;
connect(QThread::currentThread, &QThread::finished(), thread_qnam, &QObject::deleteLater);
// Whatever other setup you need.
// It'd probably be good idea to wrap this in a function.
}
// Use thread_qnam...
}