【问题标题】:Qt C++ Is static thread_local QNetworkAccessManager good choice for threaded application?Qt C++ 是静态 thread_local QNetworkAccessManager 线程应用程序的好选择吗?
【发布时间】:2023-03-12 09:27:01
【问题描述】:

我正在使用用 Qt (C++) 编写的线程应用程序。

我需要经常从不同的线程发出 get/post 请求。

Qt 文档说:

一个 QNetworkAccessManager 实例应该足以满足整个 Qt 应用。由于QNetworkAccessManager是基于QObject的,它可以 只能从它所属的线程中使用。

static thread_local QNetworkAccessManager 是否适合我的目的?

【问题讨论】:

    标签: c++ qt qtnetwork


    【解决方案1】:

    不,不是一个好的选择。

    您不应该创建静态或全局 QObject 子类实例,因为您通常需要在创建 Qt 应用程序对象之后创建它们(很多 Qt 东西取决于应用程序对象已经存在)。 C++ 并没有真正提供对何时实际创建静态对象的非常好的控制,在这里您希望拥有这种控制。

    只需使用指针和new 即可创建QNetworkAccessManager 实例,您可以根据需要创建任意数量的实例。您可以直接在正确的线程中创建它们,或者您可以在其他一些(通常是主)线程中创建它们并将它们移动到正确的线程。

    为了让它们正确销毁,当它们没有自然父级时(因为父级必须存在于同一个线程中!),将它们线程的QThread::finished 信号连接到对象QObject::deleteLater 插槽,它们将线程结束后被彻底删除。


    如果您想要一个使用当前线程的 QNAM 实例的普通函数,您可以使用线程本地静态 指针。类似的东西

    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...
    }
    

    【讨论】:

    • 我可以在函数内部使用静态 thread_local QNetworkAccessManager 来防止每次创建对象以减少内存使用吗?
    • @Brew 您将在线程启动时创建一次 QNAM 对象。你可以有一个 thread_local pointer 指向该线程的 QNAM 实例。
    猜你喜欢
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多