有4条线程可分别输出"A"、"B"、"C"、"D",现在需要控制如下顺序的结果输出到界面的标签上,每个字符的间隔是200毫秒: "ABCDABCDABCD...ABCD" 共10组;请使用互斥锁加条件变量的方式来控制,创建线程的方式使用Qt的重写run函数的写法或者使用moveToThread的写法均可。使用QT
时间: 2025-03-11 12:06:08 浏览: 34
要在Qt框架下通过四个线程按指定顺序输出字符,并保证每次输出间隔200ms,同时共输出10组序列。可以采用互斥锁加上条件变量来协调这四个线程的工作流程。
### 设计思路:
- 创建一个共享资源类 `SharedResource` 来管理当前应打印的字母以及同步机制;
- 它内部维护着互斥锁和条件变量用于等待与唤醒相应的线程;
- 每个负责打印特定字母(`A`, `B`, `C`, 或者 `D`) 的线程会检查是否轮到了自己,如果还没轮到则挂起自身直到接收到通知;
- 当某个线程完成了它的任务后更新状态并触发下一个字母对应的线程继续工作。
```cpp
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QMutex>
#include <QWaitCondition>
class SharedResource {
public:
char currentChar = 'A'; // 起始应该打印的字母
int count = 0; // 记录已经完成的组合次数
QMutex mutex;
QWaitCondition cond;
void printAndNotify(char ch) {
unique_lock<QMutex> lock(mutex);
while (currentChar != ch && count < 40) { // 等待轮到自己或者是所有都已完成
cond.wait(lock); // 阻塞此线程
}
if(count >= 40)
return ;
qDebug() << ch; // 输出相应内容
++count;
if(ch == 'D') // 如果到达了最后一个字母,则重置回第一个字母'A'
currentChar='A';
else
currentChar=ch+1;
if(currentChar > 'D')
currentChar -= 4 ; // 循环处理后的修正
cond.wakeAll(); // 唤醒其他等待中的线程去竞争执行机会
}
};
// 自定义线程类模板化以便复用
template<char T>
class PrintWorker : public QObject{
protected:
void run() override {
static auto* res = qApp->property("sharedRes").value<SharedResource*>();
for(int i=0;i<10;++i){
res->printAndNotify(T);
msleep(200); // 使用静态休眠模拟定时器效果
}
}
};
```
为了将上述设计集成进Qt应用程序中,我们可以这样做:
#### 主函数部分:
```cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto sr = new SharedResource();
a.setProperty("sharedRes", QVariant::fromValue(sr));
// 利用lambda表达式简化创建不同线程的过程
std::function<void(QThread*)> createWorker = [](QThread* thread)->void {
QObject* obj = nullptr;
switch(thread->threadId().toInt()%4){ // 根据ID简单区分出四种类别之一
case 0:obj=new PrintWorker<'A'>;break;
case 1:obj=new PrintWorker<'B'>;break;
case 2:obj=new PrintWorker<'C'>;break;
default)obj=new PrintWorker<'D'>;break;
}
obj->moveToThread(thread);
connect(thread,&QThread::started,obj,SLOT(run()));
thread->start();
};
QList<QThread*> threads;
for(int i=0;i<4;++i){
threads.append(new QThread());
createWorker(threads.last());
}
QObject::connect(&a,SIGNAL(aboutToQuit()),[&](){
foreach(auto t, threads)t->quit();
qDeleteAll(threads.begin(), threads.end());
});
return a.exec();
}
```
请注意这个例子假设了一个简单的环境,在实际应用里你需要更复杂的状态管理和异常保护等措施。而且这里直接用了qDebug来进行字符串输出,你可以替换为向UI组件发送信号等方式以达到显示目的。
阅读全文
相关推荐


















