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();
}
相关推荐
菥菥爱嘻嘻11 分钟前
JS手写代码篇---手写ajax
开发语言·javascript·ajax
江梦寻17 分钟前
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
开发语言·后端·python·macos·架构·策略模式
霖檬ing19 分钟前
Python——MySQL远程控制
开发语言·python·mysql
qq_429879671 小时前
省略号和可变参数模板
开发语言·c++·算法
优秀的颜2 小时前
计算机基础知识(第五篇)
java·开发语言·分布式
CodeWithMe2 小时前
【C/C++】std::vector成员函数清单
开发语言·c++
uyeonashi2 小时前
【QT控件】输入类控件详解
开发语言·c++·qt
iCxhust3 小时前
Prj10--8088单板机C语言8259测试(1)
c语言·开发语言
крон6 小时前
【Auto.js例程】华为备忘录导出到其他手机
开发语言·javascript·智能手机
zh_xuan7 小时前
c++ 单例模式
开发语言·c++·单例模式