Qt 多线程

写法1

//.h
class TimeConsuming : public QObject {
    Q_OBJECT
public:
    explicit TimeConsuming(QObject* parent = nullptr);

    void working();
};

//在主线程的使用
auto* thread = new QThread;
auto* work = new TimeConsuming;
work->moveToThread(thread);
QObject::connect(thread, &QThread::started, work, &TimeConsuming::working);
QObject::connect(thread, &QThread::finished, work, &TimeConsuming::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();

个人在耗时但一次的操作中使用较多

写法2

//.h
class Thread : public QThread {
    Q_OBJECT
public:
    explicit Thread(QObject* parent = nullptr);
    ~Thread();

    void launch(bool b); //启动/关闭
protected:
    void run() override;

private:
    QMutex m_mutex;
    bool m_isRuning = false;//退出循环的条件
}

//.cpp
Thread::Thread(QObject* parent)
    : QThread { parent }
{}

Thread::~Thread()
{
    launch(false);
    if (isRunning())
        wait();
}

void Thread::run()
{
     for (;;) {
        QThread::msleep(1);
         ...
        if (!m_isRuning)
            break;
     }
}

//见解释1
void Thread::launch(bool b)
{
    QMutexLocker locker(&m_mutex);
    m_isRuning = b;
    if (m_isRuning)
        start();
}

//主线程中的使用
auto* thread=new Thread;
thread->launch(true);//启动

thread->launch(false);//关闭

解释1:如果未对退出循环变量m_isRuning上锁,多个线程时,线程被系统调度是不确定的,主线程调用关闭后又接着释放线程,由于子线程的循环里的退出标志还未修改,然后主线程进行了释放,则导致线程在死循环无法退出,Qt会提示“qthread destroyed while thread is still running”。

使用了单例模式,再加上又通讯操作,就很容易出现线程被销毁,但依然被执行的问题。

QMutex

QMutex 是强制互斥的基本类。线程锁定互斥锁,以便获得对共享资源的访问权限。如果第二个线程在互斥锁已锁定的情况下尝试锁定该互斥锁,则第二个线程将处于休眠状态,直到第一个线程完成其任务并解锁互斥锁。

QReadWriteLock

QReadWriteLock 类似于 QMutex,不同之处在于它区分了“读取”和“写入”访问。当一段数据没有被写入时,多个线程同时从中读取是安全的。QMutex 强制多个读取器轮流读取共享数据,但 QReadWriteLock 允许同时读取,从而提高并行度。

QMutex与QMutexLocker的关系

QMutexLocker通常创建为局部变量,QMutexLocker在创建时传入一个并未锁定(若是锁定可用relock重新锁定或unlock解锁)的QMutex指针变量,并且会将QMutex变量锁定,在释放时会将QMutex变量解锁。(QMutexLocker创建时将传入的QMutex锁定,释放时将传入的QMutex解锁)

//QMutex的用法
void Thread::run()
{
   m_mutex->lock();//互斥锁锁定

    //...操作内容
    
    m_mutex->unlock();//互斥锁解锁
}

//QMutexd搭配QMutexLocker的用法
void Thread::run()
{
   //创建QMutexLocker的局部变量,并将类中互斥锁指针传入(此处互斥锁被locker锁定)
   QMutexLocker locker(m_mutex);

    //...操作内容

   //当locker作用域结束locker将互斥锁解锁
}

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值