使用 QtConcurrent::run() 修改成员变量?

Posted

技术标签:

【中文标题】使用 QtConcurrent::run() 修改成员变量?【英文标题】:Modifying member variables with QtConcurrent::run()? 【发布时间】:2018-07-05 12:19:51 【问题描述】:

假设我有一个类MyClass,其中包含一个非常复杂且缓慢的函数slowFunction(),我想在另一个线程中执行它,为此我正在使用Qtconcurrent::run,这是一个sn-p:

void MyClass::startAnalysis() 
     //Run slowFunction in another thread
     QtConcurrent::run(this, &MyClass::slowFunction);


void MyClass:slowFunction() 
     for(int i = 0; i < 100; i++) 
         qDebug() << this << i;
     

我面临的主要问题是如果slowFunction()MyClass 的成员变量执行任何操作,我(最终)会崩溃。另外,就像上面的代码一样,当我尝试输出指针 this 时,我也会崩溃!。

修改QtConcurrent::run执行的函数内的成员变量有什么问题吗?

【问题讨论】:

MyClass 的实例很可能在线程开始运行之前被破坏。你能把调用startAnalysis的代码贴出来吗? MyClass 的正确实例不会被破坏,我敢肯定。 问题很可能不在您向我们展示的代码中,这就是为什么除非您透露更多有关您的问题,否则我们将无法提供帮助。 我没有使用您提供的代码示例重现“this”上的崩溃。 更多代码会有所帮助,但我个人同意 Yuki,您的“this”可能已被删除,而您的慢速函数仍在使用它。 【参考方案1】:

您需要使用 QMutex 保护对成员变量的访问。

void MyClass 

...
private:
QMutex mutex;

然后,每当您访问并发使用的变量时,您都会用锁保护它。


QMutexLocker locker(&mutex);
// access variable

在线程或QConcurrent中修改成员变量并没有错,但你需要保护它。

【讨论】:

事实上这是主要问题,在我的“slowFunction()”中,我调用了一个不是线程安全的库。因此,在该库中添加适当的互斥锁就可以了。【参考方案2】:

在此示例中,如果我使用 QFuture,则类实例会根据需要保持活动状态。

class MyClass : QObject 
public:
    void LongFunction() 
        for( int count = 0; count < 5; count++ ) 
            sleep( 1 );
            std::cout << "Ping long!" << std::endl;
        
    

    void run_c() 
        QFuture<void> future = QtConcurrent::run(this, &MyClass::LongFunction);
    


;

int main(int argc, char *argv[])

    MyClass c;
    c.run_c();

【讨论】:

以上是关于使用 QtConcurrent::run() 修改成员变量?的主要内容,如果未能解决你的问题,请参考以下文章

在 QtConcurrent::run 中使用 QSqlDatabase 连接(伪连接池)

是否可以将 QtConcurrent::run() 与类的函数成员一起使用

使用 QtConcurrent::run 在单独的线程上连接信号/插槽

如何将 QtConcurrent::run 函数(或类似函数)中的 progressText 传递给 QFutureWatcher?

在 c++11 模式下使用带有仅移动参数的 QtConcurrent::run

停止由 QtConcurrent::run 启动的线程?