Qt采用多线程实现ABAB交叉打印

Qt采用多线程实现ABAB交叉打印

流程分析

  • 黑色线条和红色线条为两个线程内部自己的流程
  • 蓝色线条为整个进程的流程
  • 整个交替流程的打印

方法1:采用QWaitCondition(等待条件)实现

cpp 复制代码
// 等待条件和线程锁
class PublicData
{
public:
    static QMutex sm_Mutex;
    static QWaitCondition sm_WaitConA;
    static QWaitCondition sm_WaitConB;
};

QMutex PublicData::sm_Mutex;
QWaitCondition PublicData::sm_WaitConA;
QWaitCondition PublicData::sm_WaitConB;

// 打印A的线程
class PrintAThread : public QThread
{
    Q_OBJECT
public:
    explicit PrintAThread(QObject *parent = nullptr);

protected:
    void run() override;
};

PrintAThread::PrintAThread(QObject *parent) : QThread(parent)
{

}

void PrintAThread::run()
{
    PublicData::sm_Mutex.lock();

    while (true)
    {
    	// 等待打印B的线程唤醒它
        PublicData::sm_WaitConB.wait(&PublicData::sm_Mutex);
        qDebug() << "A";
        // 唤醒打印B的线程
        PublicData::sm_WaitConA.wakeAll();
    }

    PublicData::sm_Mutex.unlock();
}

// 打印B的线程
class PrintBThread : public QThread
{
    Q_OBJECT
public:
    explicit PrintBThread(QObject *parent = nullptr);

protected:
    void run() override;

};

PrintBThread::PrintBThread(QObject *parent) : QThread(parent)
{

}

void PrintBThread::run()
{
    PublicData::sm_Mutex.lock();

    while (true)
    {
    	// 等待打印A的线程唤醒它
        PublicData::sm_WaitConA.wait(&PublicData::sm_Mutex);
        qDebug() << "B";
        // 唤醒打印A的线程
        PublicData::sm_WaitConB.wakeAll();
    }

    PublicData::sm_Mutex.unlock();
}

// 测试函数
void Test()
{
    unique_ptr<PrintAThread> upThreadA = std::make_unique<PrintAThread>();
    unique_ptr<PrintBThread> upThreadB = std::make_unique<PrintBThread>();

    upThreadA->start();
    upThreadB->start();

    // 让线程都进入等待状态
    QThread::msleep(100);

    PublicData::sm_WaitConB.wakeAll();          // 唤醒,让 A 开始打印

    upThreadA->wait();
    upThreadB->wait();
}

方法2:采用QSemaphore(信号量)实现

信号量的实现方式逻辑与上类似

cpp 复制代码
//  信号量
class PublicData
{
public:
    static QSemaphore sm_SemphoreA;
    static QSemaphore sm_SemphoreB;
};

QSemaphore PublicData::sm_SemphoreA(1);
QSemaphore PublicData::sm_SemphoreB(1);


// 打印A的线程
class PrintAThread : public QThread
{
    Q_OBJECT
public:
    explicit PrintAThread(QObject *parent = nullptr);

protected:
    void run() override;
};

PrintAThread::PrintAThread(QObject *parent) : QThread(parent)
{

}

void PrintAThread::run()
{
    while (true)
    {
        PublicData::sm_SemphoreA.acquire();
        qDebug() << "A";
        PublicData::sm_SemphoreB.release();
    }
}

// 打印B的线程
class PrintBThread : public QThread
{
    Q_OBJECT
public:
    explicit PrintBThread(QObject *parent = nullptr);

protected:
    void run() override;

};

PrintBThread::PrintBThread(QObject *parent) : QThread(parent)
{

}

void PrintBThread::run()
{
    while (true)
    {
        PublicData::sm_SemphoreB.acquire();
        qDebug() << "B";
        PublicData::sm_SemphoreA.release();
    }
}

// 测试函数
void Test()
{
    unique_ptr<PrintAThread> upThreadA = std::make_unique<PrintAThread>();
    unique_ptr<PrintBThread> upThreadB = std::make_unique<PrintBThread>();
	
	// 取出B的信号量,让A先进入打印,然后再交替
    PublicData::sm_SemphoreB.acquire();

    upThreadA->start();
    upThreadB->start();

    upThreadA->wait();
    upThreadB->wait();
}
相关推荐
侃侃_天下5 小时前
最终的信号类
开发语言·c++·算法
echoarts6 小时前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix6 小时前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题7 小时前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说7 小时前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔7 小时前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号8 小时前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_8 小时前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty8 小时前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再8 小时前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame