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();
}
相关推荐
白日梦想家-K14 分钟前
题单【模拟与高精度】
开发语言·c++·算法
鹦鹉00727 分钟前
IO流中的字节流
java·开发语言·后端
重生之我是Java开发战士33 分钟前
【C语言】内存函数与数据在内存中的存储
c语言·开发语言·算法
haaaaaaarry37 分钟前
Element Plus常见基础组件(二)
开发语言·前端·javascript
AI_RSER1 小时前
第一篇:【Python-geemap教程(三)上】3D地形渲染与Landsat NDVI计算
开发语言·python·3d·信息可视化·遥感·gee
WSSWWWSSW1 小时前
Python编程基础与实践:Python循环结构基础
开发语言·python
极客BIM工作室1 小时前
深入理解C++中的Lazy Evaluation:延迟计算的艺术
开发语言·c++
im_AMBER2 小时前
学习日志25 python
开发语言·python·学习
南棱笑笑生2 小时前
20250802让飞凌OK3576-C开发板在飞凌的Android14下【rk3576_u选项】适配NXP的WIFIBT模块88W8987A的蓝牙
c语言·开发语言
吉凶以情迁3 小时前
window服务相关问题探索 go语言服务开发探索调试
linux·服务器·开发语言·网络·golang