QT 多线程 阻塞超时等待子线程的信号,子线程不退出
时间: 2024-10-12 10:10:38 浏览: 5
在Qt中,处理多线程时,特别是当主线程需要等待子线程完成并接收其结果时,通常使用`QWaitCondition`、`QMutex`或`QSemaphore`来协调同步。如果你希望在一定时间内等待子线程发送信号,但子线程不会被强制退出,你可以使用`QThread::wait()`函数结合一个计时器或者`QEventLoop`。
以下是一个简单的例子,展示了如何创建一个子线程,该线程有一个信号(例如`signalFinished()`),主线程等待这个信号直到特定时间后超时:
```cpp
#include <QObject>
#include <QThread>
#include <QTimer>
#include <QSignalMapper>
class WorkerThread : public QThread {
public:
explicit WorkerThread(QObject* parent = nullptr) : QThread(parent), done(false) {}
signals:
void signalFinished();
protected:
virtual void run() override {
// 这里执行你的耗时任务
// ...
done = true; // 设置标志表示任务已完成
emit signalFinished(); // 发送信号通知主线程
}
private:
bool done;
};
class MainWindow : public QMainWindow {
public slots:
void startTask(int timeoutMS) {
WorkerThread workerThread;
// 创建信号映射器,用于转换WorkerThread发出的信号到我们能接收到的类型
QSignalMapper mapper;
connect(&workerThread, &WorkerThread::signalFinished, &mapper, &QSignalMapper::map);
// 启动子线程
workerThread.start();
// 使用信号映射器确保信号到达正确槽函数
QObject::connect(&mapper, &QSignalMapper::mapped, this, [timeoutMS](bool finished) {
if (finished && timeoutMS > 0) { // 如果超时并且确实完成了
QTimer::singleShot(timeoutMS, this, &MainWindow::handleTimeout);
} else {
handleFinished();
}
});
// 主线程开始等待,最多等待指定毫秒数
QTimer::singleShot(timeoutMS, &mapper, SLOT(map(true))); // 假设信号已经到来,否则超时后调用map(true)
}
private slots:
void handleTimeout() {
qDebug() << "Timeout reached, handling accordingly.";
// 这里处理超时情况
}
void handleFinished() {
qDebug() << "Worker thread finished normally.";
// 这里处理任务完成的情况
}
};
```
在这个例子中,主线程启动子线程并连接到它的信号。如果子线程在给定的时间内没有发出信号,主线程会在超时时调用`handleTimeout`。如果子线程在超时前发出信号,主线程会调用`handleFinished`。