Qt之QtConcurrent

一 什么是QtConcurrent?

Concurrent是并发的意思,而QtConcurrent同std一样,是一个命名空间(namespace)。提供了一些高级的 API,使得在编写多线程的时候,无需使用低级线程原语,如读写锁,等待条件或信号。使用QtConcurrent编写的程序会根据可用的处理器内核数自动调整使用的线程数。

对于QtConcurrent真正要学习的是该命名空间下定义的函数。下面要讲的就是QtConcurrent::run函数的使用方法。

二 QtConcurrent::run()运行示例

每调用一次QtConcurrent::run()函数,就新建立一个线程。

示例1:将普通函数运行在两个不同的线程中

#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"

QString func1()
{
	qDebug()<<"我是func2函数";
}
Qstring func2(QString name)
{
    qDebug() << name << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    
    QFuture<QString> fut1 = QtConcurrent::run(func1);// 1.用QFuture获取该函数的运行结果
    QFuture<QString> fut2 = QtConcurrent::run(func2, QString("Thread 1"));//2.参数2:向func函数传递的参数
	QString result1 = fut1.result();
	QString result2 = fut2.result();
    fut1.waitForFinished();
    fut2.waitForFinished();
} 
//输出结果如下:
"Thread 1" from QThread(0x1b74fd2ebc0, name = "Thread (pooled)")
"Thread 2" from QThread(0x1b74fd534e0, name = "Thread (pooled)") 
函数原型:
QFuture<T> QtConcurrent::run(Function func, ...)

示例2:成员函数

  • 将类中的成员函数运行在某一个线程中,可将指向该类实例的 引用或指针 作为 QtConcurrent::run 的第一个参数传递进去;
  • 常量成员函数传递常量引用 (const reference),而非常量成员函数一般传递指针 (pointer)
#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
class A
{
public:
   A()
   {
   	std::cout << "我是 A 的构造函数" << std::endl;
   };

   QString m_func(QString name)
   {
   	m_name = name; 
   	std::cout << "我是 A 的成员函数" << std::endl;
   }
   QString m_name;
};

int main(int argc, char **argv)
{
   QApplication app(argc, argv);
   QByteArray bytearray = "hello world";
	A *a = new A();
    QFuture<QString> fut2 = QtConcurrent::run(bytearray,&QByteArray::split,',');//1.调用QByteArray的常量成员函数split(),传递常量引用,bytearray
   QFuture<QByteArray> fut3 = QtConcurrent::run(a,&A::m_func, QString("Thread 2"));//2.非常量成员函数运行在一个新的线程,传递指针

   QString result2 = fut2.result();
   QString result3 = fut3.result();

   fut2.waitForFinished();
   fut3.waitForFinished();
} 
//输出结果如下:
"Thread 1" from QThread(0x1b74fd2ebc0, name = "Thread (pooled)")
"Thread 2" from QThread(0x1b74fd534e0, name = "Thread (pooled)") 

示例3:线程池的应用

如果要为其指定线程池,可以将线程池的指针作为第一个参数传递进去

#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
using namespace QtConcurrent;
 
void func(QString name)
{
    qDebug() << name << "from" << QThread::currentThread();
}
 
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QThreadPool pool;
    pool->setMaxThreadCount(QThreadPool::globalInstance()->maxThreadCount());//setMaxThreadCount设置最大线程数,maxThreadCount()获取该计算机可运行的线程数
    QFuture<void> fut1 = run(&pool,func, QString("Thread 1"));
    fut1.waitForFinished();
} 
函数原型:
QFuture<T> QtConcurrent::run(&pool, Function func, ...)
  • 17
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用QtConcurrent和QFile来实现线程读取文件,可以通过以下步骤实现: 1. 引入头文件 ```cpp #include <QtConcurrent/QtConcurrent> #include <QFile> ``` 2. 定义任务函数 ```cpp void readFile(const QString& filePath) { QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QString data = QString::fromUtf8(file.readAll()); file.close(); emit readFinished(data); } } ``` 3. 在主线程中调用QtConcurrent::run()函数,该函数会在后台线程中执行任务函数,并返回一个QFuture对象,用于检查任务执行状态。 ```cpp QString filePath = "file.txt"; QFuture<void> future = QtConcurrent::run(readFile, filePath); ``` 4. 在主线程中连接任务函数的信号readFinished()到槽函数,用于处理读取到的数据。 ```cpp connect(this, &MainWindow::readFinished, this, &MainWindow::onReadFinished); ``` 5. 在任务函数中定义一个信号readFinished(),用于向主线程发送读取到的数据。 ```cpp signals: void readFinished(QString data); ``` 6. 在槽函数中处理读取到的数据,例如显示在文本框中。 ```cpp void MainWindow::onReadFinished(QString data) { ui->textEdit->setText(data); } ``` 需要注意的是,由于文件读取可能会比较耗时,因此我们需要确保在任务执行期间 UI 线程不会被阻塞,否则应用程序会出现假死现象。为了避免这种情况,建议将文件读取任务放在一个单独的线程中执行,而不是在 UI 线程中执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值