Qt线程中访问容器vector导致程序崩溃,QMutex互斥锁的使用

⌚Time: 2023-01-02 13:45:01

👨‍💻Author: Jack Ge

c++的map、vector等容器都不是安全的,所以如果要在多线程环境中使用容器,就必须线程同步

例子

在线程函数中,每隔一定时间对全局容器进行清空和重新赋值操作


void func(){

    QThread::msleep(300);

    while(1){

        //清空数据

        QThread::msleep(100);

        QVector<int>().swap(g_vector);

        QThread::msleep(100);

        for(int i=0;i<10;i++){

            g_vector.push_back(i);

        }

    }

}

在主函数中,定时输出容器内容


int main(int argc, char *argv[])

{

    QCoreApplication a(argc, argv);



    for(int i=0;i<10;i++){

        g_vector.push_back(i);

    }

    QFuture<void> fu=QtConcurrent::run(func);



    while(1){

        for(int i=0;i<10;i++){

            printf("%d ",g_vector.at(i));

        }

        printf("\n");

        QThread::msleep(1000);

    }

    return a.exec();

}


最后的结果,可以看到,由于线程中对容器进行清空操作还没有重新赋值,正好主函数要进行容器的输出,这样就会造成数据的崩溃,主函数进行了几次while循环后崩溃

在使用线程时数据读写的冲突,导致程序崩溃

这时候就需要使用QMutex互斥锁保护变量,多线程在使用到同一变量时,加锁进行保护


void func(){

    QThread::msleep(300);

    while(1){

        //清空数据

        g_mutex.lock();//上锁

        QThread::msleep(100);

        QVector<int>().swap(g_vector);

        QThread::msleep(100);

        for(int i=0;i<10;i++){

            g_vector.push_back(i);

        }

        g_mutex.unlock();//解锁

    }

}

    while(1){

        g_mutex.lock();//上锁

        for(int i=0;i<10;i++){

            printf("%d ",g_vector.at(i));

        }

        printf("\n");

        QThread::msleep(1000);

        g_mutex.unlock();//解锁

    }

结果程序正常运行没有崩溃

完整代码


#include <QCoreApplication>

#include <QVector>

#include <QThread>

#include <QFuture>

#include <QtConcurrent/QtConcurrent>

#include <QMutex>

QVector<int> g_vector;

QMutex g_mutex;

void func(){

    QThread::msleep(300);

    while(1){

        //清空数据

        g_mutex.lock();

        QThread::msleep(100);

        QVector<int>().swap(g_vector);

        QThread::msleep(100);

        for(int i=0;i<10;i++){

            g_vector.push_back(i);

        }

        g_mutex.unlock();

    }

}

int main(int argc, char *argv[])

{

    QCoreApplication a(argc, argv);



    for(int i=0;i<10;i++){

        g_vector.push_back(i);

    }

    QFuture<void> fu=QtConcurrent::run(func);



    while(1){

        g_mutex.lock();

        for(int i=0;i<10;i++){

            printf("%d ",g_vector.at(i));

        }

        printf("\n");

        QThread::msleep(1000);

        g_mutex.unlock();

    }

    return a.exec();

}