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();
}
相关推荐
CC.GG几秒前
【C++】C++11(二)可变模板参数模板、新的类功能、包装器(function、bind)
开发语言·c++
Yupureki10 分钟前
《算法竞赛从入门到国奖》算法基础:入门篇-分治
c语言·开发语言·数据结构·c++·算法·贪心算法
无心水13 分钟前
4、Go语言程序实体详解:变量声明与常量应用【初学者指南】
java·服务器·开发语言·人工智能·python·golang·go
ZPC821013 分钟前
psutil
开发语言·php
jiunian_cn14 分钟前
【C++】线程库
开发语言·c++
0x5315 分钟前
JAVA|智能仿真并发项目-并行与并发
java·开发语言
漫漫求18 分钟前
1、IM:基础连接
开发语言·后端·golang
gjxDaniel26 分钟前
JavaScript编程语言入门与常见问题
开发语言·javascript
kk哥889926 分钟前
C++新手入门
开发语言·c++
Hello eveybody27 分钟前
Java发明者介绍
java·开发语言