Qt多线程中的锁

9 篇文章 0 订阅

示例1:

如果不用锁,会发生什么呢?

参考:C++11多线程锁(入门)_c++线程加锁-CSDN博客

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    qDebug()<<"main:"<<QThread::currentThreadId();
    connect(this,SIGNAL(destroyed()),this,SLOT(quitThreadSlot()));
    t=new try_thread(this);
    t->start();

    t1=new try_thread(this);
    t1->start();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::quitThreadSlot()
{
    t->quit();
    t->wait();

    t1->quit();
    t1->wait();
}

为什么要quit() :回头看[2024/8/28]这段代码,发现不需要执行quit()函数

因为如果线程没有开启事件循环的话,该函数不起作用。 

int counter=0;
try_thread::try_thread(QObject *parent) : QThread(parent)
{

}
void try_thread::run()
{
    for(int i=0;i<100;i++)
    {
        counter++;
        this->msleep(10);    //每10ms休眠1次
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;
    }
}

输出结果:

main: 0x3948
son: 0x3ebc     2
son: 0x2140     2
son: 0x2140     4
son: 0x3ebc     4
son: 0x2140     6
son: 0x3ebc     6
son: 0x3ebc     8
son: 0x2140     8
son: 0x3ebc     10
son: 0x2140     10
son: 0x2140     12
son: 0x3ebc     12
son: 0x2140     14
son: 0x3ebc     14
son: 0x3ebc     16
son: 0x2140     16
son: 0x3ebc     18
son: 0x2140     18
son: 0x2140     20
son: 0x3ebc     20
son: 0x2140     22
son: 0x3ebc     22
son: 0x3ebc     24
son: 0x2140     24
son: 0x3ebc     26
son: 0x2140     26
son: 0x3ebc     28
son: 0x2140     28
son: 0x2140     30
son: 0x3ebc     30
son: 0x2140     32
son: 0x3ebc     32
son: 0x3ebc     34
son: 0x2140     34
son: 0x2140     36
son: 0x3ebc     36
son: 0x2140     38
son: 0x3ebc     38
son: 0x3ebc     40
son: 0x2140     40
son: 0x2140     42
son: 0x3ebc     42
son: 0x3ebc     44
son: 0x2140     44
son: 0x2140     46
son: 0x3ebc     46
son: 0x3ebc     48
son: 0x2140     48
son: 0x3ebc     50
son: 0x2140     50
son: 0x3ebc     52
son: 0x2140     52
son: 0x3ebc     54
son: 0x2140     54
son: 0x2140     56
son: 0x3ebc     56
son: 0x2140     58
son: 0x3ebc     58
son: 0x2140     60
son: 0x3ebc     60
son: 0x2140     62
son: 0x3ebc     62
son: 0x3ebc     64
son: 0x2140     64
son: 0x2140     66
son: 0x3ebc     66
son: 0x3ebc     68
son: 0x2140     68
son: 0x2140     70
son: 0x3ebc     70
son: 0x3ebc     72
son: 0x2140     72
son: 0x2140     74
son: 0x3ebc     74
son: 0x3ebc     76
son: 0x2140     76
son: 0x3ebc     78
son: 0x2140     78
son: 0x3ebc     80
son: 0x2140     80
son: 0x2140     82
son: 0x3ebc     82
son: 0x3ebc     84
son: 0x2140     84
son: 0x2140     86
son: 0x3ebc     86
son: 0x2140     88
son: 0x3ebc     88
son: 0x2140     90
son: 0x3ebc     90
son: 0x2140     92
son: 0x3ebc     92
son: 0x3ebc     94
son: 0x2140     94
son: 0x3ebc     96
son: 0x2140     96
son: 0x3ebc     98
son: 0x2140     98
son: 0x3ebc     100
son: 0x2140     100
son: 0x3ebc     102
son: 0x2140     102
son: 0x2140     104
son: 0x3ebc     104
son: 0x3ebc     106
son: 0x2140     106
son: 0x3ebc     108
son: 0x2140     108
son: 0x2140     110
son: 0x3ebc     110
son: 0x2140     112
son: 0x3ebc     112
son: 0x3ebc     114
son: 0x2140     114
son: 0x3ebc     116
son: 0x2140     116
son: 0x3ebc     118
son: 0x2140     118
son: 0x2140     120
son: 0x3ebc     120
son: 0x2140     122
son: 0x3ebc     122
son: 0x2140     124
son: 0x3ebc     124
son: 0x2140     126
son: 0x3ebc     126
son: 0x3ebc     128
son: 0x2140     128
son: 0x3ebc     130
son: 0x2140     130
son: 0x2140     132
son: 0x3ebc     132
son: 0x3ebc     134
son: 0x2140     134
son: 0x2140     136
son: 0x3ebc     136
son: 0x3ebc     138
son: 0x2140     138
son: 0x2140     140
son: 0x3ebc     140
son: 0x2140     142
son: 0x3ebc     142
son: 0x3ebc     144
son: 0x2140     144
son: 0x2140     146
son: 0x3ebc     146
son: 0x2140     148
son: 0x3ebc     148
son: 0x3ebc     150
son: 0x2140     150
son: 0x3ebc     152
son: 0x2140     152
son: 0x2140     154
son: 0x3ebc     154
son: 0x2140     156
son: 0x3ebc     156
son: 0x2140     158
son: 0x3ebc     158
son: 0x3ebc     160
son: 0x2140     160
son: 0x2140     162
son: 0x3ebc     162
son: 0x2140     164
son: 0x3ebc     164
son: 0x2140     166
son: 0x3ebc     166
son: 0x2140     168
son: 0x3ebc     168
son: 0x2140     170
son: 0x3ebc     170
son: 0x2140     172
son: 0x3ebc     172
son: 0x2140     174
son: 0x3ebc     174
son: 0x2140     176
son: 0x3ebc     176
son: 0x2140     178
son: 0x3ebc     178
son: 0x2140     180
son: 0x3ebc     180
son: 0x2140     182
son: 0x3ebc     182
son: 0x2140     184
son: 0x3ebc     184
son: 0x2140     186
son: 0x3ebc     186
son: 0x2140     188
son: 0x3ebc     188
son: 0x2140     190
son: 0x3ebc     190
son: 0x2140     192
son: 0x3ebc     192
son: 0x2140     194
son: 0x3ebc     194
son: 0x2140     196
son: 0x3ebc     196
son: 0x2140     198
son: 0x3ebc     198
son: 0x3ebc     200
son: 0x2140     200

counter是两个线程共用的变量。

过程是这样的:

son: 0x3ebc:counter++,变为1,休眠10ms

son: 0x2140:counter++,变为2,休眠10ms

然后就会输出:

son: 0x3ebc 2

son: 0x2140 2

上锁:

参考:

Qt 多线程同步:互斥锁QMutextLocker 、读写锁 QReadWriteLock、信号量 QSemaphore、 条件变量QWaitConditio、QThread::wait()_qt线程锁-CSDN博客

 示例2:

int counter=0;
QMutex mutex;
try_thread::try_thread(QObject *parent) : QThread(parent)
{

}
void try_thread::run()
{
    mutex.lock();
    for(int i=0;i<10;i++)
    {
        counter++;
        this->msleep(10);
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;
    }
    mutex.unlock();
}

main: 0x4c28

son: 0x3be0 1

son: 0x3be0 2

son: 0x3be0 3

son: 0x3be0 4

son: 0x3be0 5

son: 0x3be0 6

son: 0x3be0 7

son: 0x3be0 8

son: 0x3be0 9

son: 0x3be0 10

son: 0x3640 11

son: 0x3640 12

son: 0x3640 13

son: 0x3640 14

son: 0x3640 15

son: 0x3640 16

son: 0x3640 17

son: 0x3640 18

son: 0x3640 19

son: 0x3640 20

 上锁后的执行顺序:

son: 0x3be0:上锁,开始执行

    for(int i=0;i<100;i++)
    {
        counter++;
        this->msleep(10);
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;
    }

解锁。

son: 0x3640:想要上锁,发现其他线程已经上锁了,就阻塞在这儿啦,等啊等啊,解锁了,

开始执行

    for(int i=0;i<100;i++)
    {
        counter++;
        this->msleep(10);
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;
    }

然后解锁。

 示例3:

改变锁的位置:

void try_thread::run()
{
    for(int i=0;i<10;i++)
    {
        mutex.lock();
        counter++;
        this->msleep(10);
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;
        mutex.unlock();
    }
}

输出结果:

main: 0x3ec4

son: 0x4c50 1

son: 0x4cd0 2

son: 0x4c50 3

son: 0x4cd0 4

son: 0x4c50 5

son: 0x4cd0 6

son: 0x4c50 7

son: 0x4cd0 8

son: 0x4c50 9

son: 0x4cd0 10

son: 0x4c50 11

son: 0x4cd0 12

son: 0x4c50 13

son: 0x4cd0 14

son: 0x4c50 15

son: 0x4cd0 16

son: 0x4c50 17

son: 0x4cd0 18

son: 0x4c50 19

son: 0x4cd0 20

 示例4:QMutexLocker的使用

void try_thread::run()
{
    for(int i=0;i<10;i++)
    {
        QMutexLocker locker(&mutex);    //上锁
        counter++;
        this->msleep(10);
        qDebug()<<"son:"<<QThread::currentThreadId()<<"   "<<counter;    
        //执行完成后,locker被销毁,解锁
    }
}

main: 0x4f84

son: 0x1dc8 1

son: 0x1df0 2

son: 0x1dc8 3

son: 0x1df0 4

son: 0x1dc8 5

son: 0x1df0 6

son: 0x1dc8 7

son: 0x1df0 8

son: 0x1dc8 9

son: 0x1df0 10

son: 0x1dc8 11

son: 0x1df0 12

son: 0x1dc8 13

son: 0x1df0 14

son: 0x1dc8 15

son: 0x1df0 16

son: 0x1dc8 17

son: 0x1df0 18

son: 0x1dc8 19

son: 0x1df0 20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值