使用 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?