Qt中多线程的使用(二)

本文详细介绍了Qt中多线程的使用,特别是线程池的概念。讨论了QThread和QThreadPool在不同场景下的适用性,并展示了如何通过SIGNAL/SLOT和QMetaObject::invokeMethod实现线程池与外界的通信。同时,提供了实例代码说明如何利用线程池执行任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池

当线程的任务量比较大时,频繁创建和销毁线程会有很大的内存开销,此时使用QThread的方法就不合适,应该使用线程池QThreadPool。QThread适用于常驻内存的任务,QThreadPool适用于不常驻内存,任务量比较大的情况。

QRunnable 是一个非常轻量的抽象类,它的主体是纯虚函数 QRunnable::run(),我们需要继承它并实现这个函数。使用时需要将其子类的实例放进 QThreadPool 的执行队列,线程池默认会在运行后自动删除这个实例。每一个Qt程序都有一个全局的线程池,我们可以直接使用它,这就不需要手动创建和管理线程池,调用QThreadPool::globalInstance()得到,可在多个类中共同使用一个线程池。它默认最多创建 8 个线程,如果想改变最大线程数则调用 setMaxThreadCount() 进行修改,调用 activeThreadCount() 查看线程池中当前活跃的线程数。

Qt并不是推荐使用其全局线程池,何况实际的项目当中我们通常并不希望仅仅使用一个全局的线程池,而是在需要线程池的工程中都构建和维护自己一个小小的线程池。用QThreadPool pool;的方式建立一个局部线程池,并由当前类维护,可保证此线程池仅供当前类应用。

常规使用

定一个任务类例如叫 Task,继承 QRunnable 并实现虚函数 run(),Task 的对象作为 QThreadPool::start() 的参数就可以了,线程池会自动的在线程中调用 Task 的 run() 函数,异步执行。线程池中的 QRunnable 对象太多时并不会立即为每一个 QRunnable 对象创建一个线程,而是让它们排队执行,同时最多有 maxThreadCount() 个线程并行执行。

void clear()    //清除所有当前排队但未开始运行的任务
int expiryTimeout() const       //线程长时间未使用将会自动退出节约资源,此函数返回等待时间
void setExpiryTimeout(int expiryTimeout)        //设置线程回收的等待时间
int maxThreadCount() const      //线程池可维护的最大线程数量
setAutoDelete   //用来标识是否在运行结束后自动由线程池释放空间
bool waitForDone(int msecs=-1)      //等待所有线程运行结束并退出,参数为等待时间-1表示一直等待到最后一个线程退出

代码实现一个QRunnable子类,构造函数参数是其ID,run()里输出ID和休眠1到3秒,析构函数里输出ID:

class Task : public QRunnable
{
public:
    Task(int id);
    void run() Q_DECL_OVERRIDE;
    ~Task();
private:
    int m_id;
};

Task::Task(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值