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 小时前
Java-171 Neo4j 备份与恢复 + 预热与执行计划实战
java·开发语言·数据库·性能优化·系统架构·nosql·neo4j
怪兽20145 小时前
fastjson在kotlin不使用kotlin-reflect库怎么使用?
android·开发语言·kotlin
ClearLiang5 小时前
Kotlin-协程的挂起与恢复
开发语言·kotlin
彭同学学习日志6 小时前
Kotlin Fragment 按钮跳转报错解决:Unresolved reference ‘floatingActionButton‘
android·开发语言·kotlin
海域云赵从友6 小时前
破解跨境数据传输瓶颈:中国德国高速跨境组网专线与本地化 IP 的协同策略
开发语言·php
咚咚王者6 小时前
人工智能之编程进阶 Python高级:第九章 爬虫类模块
开发语言·python
怎么就重名了6 小时前
STM32+蓝牙模块+超声波模块+QT
stm32·嵌入式硬件·qt
深蓝海拓6 小时前
使matplot显示支持中文和负号
开发语言·python
syt_biancheng7 小时前
Day3算法训练(简写单词,dd爱框框,3-除2!)
开发语言·c++·算法·贪心算法
864记忆7 小时前
Qt Network 模块中的函数详解
开发语言·网络·qt