iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++ Qt QThread线程组件的具体使用是怎样的
  • 479
分享到

C/C++ Qt QThread线程组件的具体使用是怎样的

2023-06-21 20:06:28 479人浏览 八月长安
摘要

这期内容当中小编将会给大家带来有关C/C++ Qt QThread线程组件的具体使用是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。QThread库是QT中提供的跨平台多线程实现

这期内容当中小编将会给大家带来有关C/C++ Qt QThread线程组件的具体使用是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

QThread库是QT中提供的跨平台多线程实现方案,使用时需要继承QThread这个基类,并重写实现内部的Run方法,由于该库是基本库,默认依赖于QtCore.dll这个基础模块,在使用时无需引入其他模块.

实现简单多线程

QThread库提供了跨平台的多线程管理方案,通常一个QThread对象管理一个线程,在使用是需要从QThread类继承并重写内部的Run方法,并在Run方法内部实现多线程代码.

#include <QCoreApplication>#include <iOStream>#include <QThread>class MyThread: public QThread{protected:    volatile bool m_to_stop;protected:    // 线程函数必须使用Run作为开始    void run()    {        for(int x=0; !m_to_stop && (x <10); x++)        {            msleep(1000);            std::cout << objectName().toStdString() << std::endl;        }    }public:    MyThread()    {        m_to_stop = false;    }    // 用于设置结束符号为真    void stop()    {        m_to_stop = true;    }    // 输出线程运行状态    void is_run()    {        std::cout << "Thread Running = " << isRunning() << std::endl;    }    // 输出线程完成状态(是否结束)    void is_finish()    {        std::cout << "Thread Finished = " << isFinished() << std::endl;    }};int main(int arGC, char *argv[]){    QCoreApplication a(argc, argv);    // 定义线程数组    MyThread thread[10];    // 设置线程对象名字    for(int x=0;x<10;x++)    {        thread[x].setObjectName(QString("thread => %1").arg(x));    }    // 批量调用run执行    for(int x=0;x<10;x++)    {        thread[x].start();        thread[x].is_run();        thread[x].isFinished();    }    // 批量调用stop关闭    for(int x=0;x<10;x++)    {        thread[x].wait();        thread[x].stop();        thread[x].is_run();        thread[x].is_finish();    }    return a.exec();}

向线程中传递参数

线程在执行前可以通过调用MyThread中的自定义函数,并在函数内实现参数赋值,实现线程传参操作.

#include <QCoreApplication>#include <iostream>#include <QThread>class MyThread: public QThread{protected:    int m_begin;    int m_end;    int m_result;    void run()    {        m_result = m_begin + m_end;    }public:    MyThread()    {        m_begin = 0;        m_end = 0;        m_result = 0;    }    // 设置参数给当前线程    void set_value(int x,int y)    {        m_begin = x;        m_end = y;    }    // 获取当前线程名    void get_object_name()    {        std::cout << "this thread name => " << objectName().toStdString() << std::endl;    }    // 获取线程返回结果    int result()    {        return m_result;    }};int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    MyThread thread[3];    // 分别将不同的参数传入到线程函数内    for(int x=0; x<3; x++)    {        thread[x].set_value(1,2);        thread[x].setObjectName(QString("thread -> %1").arg(x));        thread[x].start();    }    // 等待所有线程执行结束    for(int x=0; x<3; x++)    {        thread[x].get_object_name();        thread[x].wait();    }    // 获取线程返回值并相加    int result = thread[0].result() + thread[1].result() + thread[2].result();    std::cout << "sum => " << result << std::endl;    return a.exec();}

QMutex 互斥同步线程

QMutex类是基于互斥量的线程同步锁,该锁lock()锁定与unlock()解锁必须配对使用,线程锁保证线程间的互斥,利用线程锁能够保证临界资源的安全性.

  • 线程锁解决的问题: 多个线程同时操作同一个全局变量,为了防止资源的无序覆盖现象,从而需要增加锁,来实现多线程抢占资源时可以有序执行.

  • 临界资源(Critical Resource): 每次只允许一个线程进行访问 (读/写)的资源.

  • 线程间的互斥(竞争): 多个线程在同一时刻都需要访问临界资源.

  • 一般性原则: 每一个临界资源都需要一个线程锁进行保护.

#include <QCoreApplication>#include <iostream>#include <QThread>#include <QMutex>static QMutex g_mutex;      // 线程锁static QString g_store;     // 定义全局变量class Producer : public QThread{protected:    void run()    {        int count = 0;        while(true)        {            // 加锁            g_mutex.lock();            g_store.append(QString::number((count++) % 10));            std::cout << "Producer -> "<< g_store.toStdString() << std::endl;            // 释放锁            g_mutex.unlock();            msleep(900);        }    }};class Customer : public QThread{protected:    void run()    {        while( true )        {            g_mutex.lock();            if( g_store != "" )            {                g_store.remove(0, 1);                std::cout << "Curstomer -> "<< g_store.toStdString() << std::endl;            }            g_mutex.unlock();            msleep(1000);        }    }};int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    Producer p;    Customer c;    p.setObjectName("producer");    c.setObjectName("curstomer");    p.start();    c.start();    return a.exec();}

QMutexLocker是在QMutex基础上简化版的线程锁,QMutexLocker会保护加锁区域,并自动实现互斥量的锁定和解锁操作,可以将其理解为是智能版的QMutex锁,该锁只需要在上方代码中稍加修改即可.

#include <QMutex>#include <QMutexLocker>static QMutex g_mutex;      // 线程锁static QString g_store;     // 定义全局变量class Producer : public QThread{protected:    void run()    {        int count = 0;        while(true)        {// 增加智能线程锁            QMutexLocker Locker(&g_mutex);            g_store.append(QString::number((count++) % 10));            std::cout << "Producer -> "<< g_store.toStdString() << std::endl;            msleep(900);        }    }};

互斥锁存在一个问题,每次只能有一个线程获得互斥量的权限,如果在程序中有多个线程来同时读取某个变量,那么使用互斥量必须排队,效率上会大打折扣,基于QReadWriteLock读写模式进行代码段锁定,即可解决互斥锁存在的问题.

QReadWriteLock 读写同步线程锁

该锁允许用户以同步读lockForRead()或同步写lockForWrite()两种方式实现保护资源,但只要有一个线程在以写的方式操作资源,其他线程也会等待写入操作结束后才可继续读资源.

#include <QCoreApplication>#include <iostream>#include <QThread>#include <QMutex>#include <QReadWriteLock>static QReadWriteLock g_mutex;      // 线程锁static QString g_store;             // 定义全局变量class Producer : public QThread{protected:    void run()    {        int count = 0;        while(true)        {            // 以写入方式锁定资源            g_mutex.lockForWrite();            g_store.append(QString::number((count++) % 10));            // 写入后解锁资源            g_mutex.unlock();            msleep(900);        }    }};class Customer : public QThread{protected:    void run()    {        while( true )        {            // 以读取方式写入资源            g_mutex.lockForRead();            if( g_store != "" )            {                std::cout << "Curstomer -> "<< g_store.toStdString() << std::endl;            }            // 读取到后解锁资源            g_mutex.unlock();            msleep(1000);        }    }};int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    Producer p1,p2;    Customer c1,c2;    p1.setObjectName("producer 1");    p2.setObjectName("producer 2");    c1.setObjectName("curstomer 1");    c2.setObjectName("curstomer 2");    p1.start();    p2.start();    c1.start();    c2.start();    return a.exec();}

QSemaphore 基于信号线程锁

信号量是特殊的线程锁,信号量允许N个线程同时访问临界资源,通过acquire()获取到指定资源,release()释放指定资源.

#include <QCoreApplication>#include <iostream>#include <QThread>#include <QSemaphore>const int SIZE = 5;unsigned char g_buff[SIZE] = {0};QSemaphore g_sem_free(SIZE); // 5个可生产资源QSemaphore g_sem_used(0);    // 0个可消费资源// 生产者生产产品class Producer : public QThread{protected:    void run()    {        while( true )        {            int value = qrand() % 256;            // 若无法获得可生产资源,阻塞在这里            g_sem_free.acquire();            for(int i=0; i<SIZE; i++)            {                if( !g_buff[i] )                {                    g_buff[i] = value;                    std::cout << objectName().toStdString() << " --> " << value << std::endl;                    break;                }            }            // 可消费资源数+1            g_sem_used.release();            sleep(2);        }    }};// 消费者消费产品class Customer : public QThread{protected:    void run()    {        while( true )        {            // 若无法获得可消费资源,阻塞在这里            g_sem_used.acquire();            for(int i=0; i<SIZE; i++)            {                if( g_buff[i] )                {                    int value = g_buff[i];                    g_buff[i] = 0;                    std::cout << objectName().toStdString() << " --> " << value << std::endl;                    break;                }            }            // 可生产资源数+1            g_sem_free.release();            sleep(1);        }    }};int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    Producer p1;    Customer c1;    p1.setObjectName("producer");    c1.setObjectName("curstomer");    p1.start();    c1.start();    return a.exec();}

上述就是小编为大家分享的C/c++ Qt QThread线程组件的具体使用是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网其他教程频道。

--结束END--

本文标题: C/C++ Qt QThread线程组件的具体使用是怎样的

本文链接: https://www.lsjlt.com/news/300564.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C/C++ Qt QThread线程组件的具体使用是怎样的
    这期内容当中小编将会给大家带来有关C/C++ Qt QThread线程组件的具体使用是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。QThread库是QT中提供的跨平台多线程实现...
    99+
    2023-06-21
  • C/C++ Qt ToolBar菜单组件的具体使用是怎样的
    C/C++ Qt ToolBar菜单组件的具体使用是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。ToolBar工具栏在所有窗体应用程...
    99+
    2023-06-21
  • C/C++ Qt QChart绘图组件的具体使用是怎么样的
    这篇文章给大家介绍C/C++ Qt QChart绘图组件的具体使用是怎么样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。QtCharts 组件是QT中提供图表绘制的模块,该模块可以方便的绘制常规图...
    99+
    2023-06-21
  • C/C++QtQThread线程组件的具体使用
    QThread库是QT中提供的跨平台多线程实现方案,使用时需要继承QThread这个基类,并重写实现内部的Run方法,由于该库是基本库,默认依赖于QtCore.dll这个基础模块,在...
    99+
    2024-04-02
  • QT线程QThread的使用介绍
    目录1. 概述2. moveThread 示例3. QThread 示例4. 总结1. 概述 QThread 有两种使用方式 QObject::moveToThread()派生QTh...
    99+
    2024-04-02
  • C++的Qt MdiArea多窗体组件怎么使用
    本篇内容主要讲解“C++的Qt MdiArea多窗体组件怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++的Qt MdiArea多窗体组件怎么使用”吧!MDI窗体控...
    99+
    2023-06-21
  • C/C++QtQChart绘图组件的具体使用
    QtCharts 组件是QT中提供图表绘制的模块,该模块可以方便的绘制常规图形,Qtcharts 组件基于GraphicsView模式实现,其核心是QChartView和QChart...
    99+
    2024-04-02
  • C/C++QtToolBar菜单组件的具体使用
    ToolBar工具栏在所有窗体应用程序中都广泛被使用,使用ToolBar可以很好的规范菜单功能分类,用户可根据菜单栏来选择不同的功能,Qt中默认自带ToolBar组件,当我们以默认方...
    99+
    2024-04-02
  • C/C++ Qt MdiArea 多窗体组件应用教程
    MDI多窗体组件,主要用于设计多文档界面应用程序,该组件具备有多种窗体展示风格,其实现了在父窗体中内嵌多种子窗体的功能,使用MDI组件需要在UI界面中增加mdiArea控件容器,我们...
    99+
    2024-04-02
  • 怎么使用C/C++ QT的QChart绘制组件
    本篇内容主要讲解“怎么使用C/C++ QT的QChart绘制组件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用C/C++ QT的QChart绘制组件”吧!QtCharts 组件是QT中提...
    99+
    2023-06-25
  • C# Volatile的具体使用
    目录​1.Overview2.Detail3.Conclusion4.Reference​1.Overview 经常研究.NET源码库的小伙伴会经常看到一个关...
    99+
    2024-04-02
  • C#打印源码的具体实现是怎样的
    本篇文章给大家分享的是有关C#打印源码的具体实现是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C#打印源码也是打印控件的功能之一,这里介绍的C#打印源码可以实现自动打印...
    99+
    2023-06-17
  • C/C++ Qt StatusBar底部状态栏应用是怎么样的
    这篇文章将为大家详细讲解有关C/C++ Qt StatusBar底部状态栏应用是怎么样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Qt窗体中默认会附加一个Qstatu...
    99+
    2023-06-21
  • C#二维数组与多维数组的具体使用
    目录1、二维数组2、初始化二维数组3、访问二维数组种的元素C# 中同样支持多维数组(也可称为矩形数组),它可以是二维的,也可以是三维的,多维数组中的数据以类似表格(行、列)的形式存储...
    99+
    2023-05-15
    C#二维数组与多维数组 C#二维数组 C#多维数组
  • C#Replace替换的具体使用
    目录前言一、String.Replace() 的几个重载1、Replace(Char, Char)2、String.Replace(String, String) ...
    99+
    2023-02-19
    C# Replace替换 C# Replace
  • C/C++ Qt StringListModel字符串列表映射组件怎么使用
    这篇文章主要介绍“C/C++ Qt StringListModel字符串列表映射组件怎么使用”,在日常操作中,相信很多人在C/C++ Qt StringListModel字符串列表映射组件怎么使用问题...
    99+
    2023-06-21
  • C++ deque容器的具体使用
     deque 是 double-ended queue 的缩写,又称双端队列容器。 和 vector 不同的是,deque 还擅长在序列头部添加或删除元素,所耗费的时间复杂...
    99+
    2024-04-02
  • C++ setw()函数的具体使用
    C++ setw() 函数用于设置字段的宽度,语法格式如下: setw(n) n 表示宽度,用数字表示。 setw() 函数只对紧接着的输出产生作用。 当后面紧跟着的输出字段长度小...
    99+
    2023-03-09
    C++ setw()
  • C#中{get;set;}的具体使用
    在C#程序中经常会看到set,get的配套使用,很多人不知道它的用途。我就在这向大家讲讲,也加深一下自己的印象。 //这里有两个类 public class person1 { ...
    99+
    2023-02-06
    C# {get;set;} C# GET SET
  • C# goto语句的具体使用
    C# goto 语句用于直接在一个程序中转到程序中的标签指定的位置,标签实际上由标识符加上冒号构成。 语法形式如下。 goto Labell; 语句块 1; Labell...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作