如何在长时间运行的方法中等待信号?
How to wait for signal in long running method?
目前,我正在flex&bison的基础上开发一种简单的编程语言。
为此,我首先构建抽象语法树(AST(并继续对其进行评估。在评估期间,应能够收到用户输入。用户输入是在Qt-GUI中完成的。ast-evaluation-过程在由 GUI 创建的线程工作线程对象中运行。 我的问题是:哪一种是最好的方法,"阻止"正在运行的flex&bison评估过程,然后从GUI接收用户输入,然后继续执行该过程? 不幸的是,我不知道如何将评估过程分成两部分以捕获来自GUI的用户输入信号,然后在插槽中继续"拆分过程"。 我当前的解决方案(在我看来很差(在评估过程中使用无限循环,直到线程工人对象中的布尔成员变量 (_hasUserInput( 设置为 true。用户输入后,GUI 发出信号。相应的插槽位于线程工作器对象内部。插槽接收用户输入,例如作为 QString 并设置相应的成员变量。此外,布尔变量设置为 true,因此可以保留评估过程的无限循环,可以处理用户输入并继续评估。
功能原理:
GUI -->启动线程(worker-对象(-->启动长期运行过程
伪代码中的示例:
class ThreadWorker : public QObject {
...
// Slot, that reacts to the signal from the GUI
void userInput(const QString &input) {
_userInput = input;
_hasUserInput = true;
}
// evaluation-procedure
void doEvaluation() {
// evaluation of the AST
...
emit userInputRequired();
while (!hasUserInput){ // Check if user input has been done
qApp -> processEvents(); // to react to events
}
do something with user input;
continue valuation; // Processing of user input and continuation of the procedure
}
...
};
我试图尽可能好地描述我的问题,并希望它能奏效。如果您需要更详细的信息,请询问。 提前非常感谢您的帮助!
由于您已经将工作线程分解到QObject
中,因此您永远不需要调用processEvents()
。相反,将 AST 评估分解为根据需要执行的小块。我还使公共接口是线程安全的 - 因此您可以直接从任何线程调用它。
// see https://stackoverflow.com/a/40382821/1329652
bool isSafe(QObject * obj);
template <typename Class, typename... Args> void postCall(Class * obj, void (Class::*method)(Args...), Args&& ...args);
class ASTWorker : public QObject {
Q_OBJECT
QBasicTimer m_evaluateTimer; // a bit lower overhead than QTimer
void timerEvent(QTimerEvent * ev) override {
if (ev->timerId() == m_evaluateTimer.timerId())
evaluateImpl();
}
void evaluateImpl() {
bool evaluationDone = {};
QThread::msleep(10); // emulate evaluating a chunk of AST
if (!evaluationDone && !m_evaluateTimer.isActive())
m_evaluateTimer.start(0, this);
else if (evaluationDone)
m_evaluateTimer.stop();
}
public:
using QObject::QObject;
/// Thread-safe
Q_SLOT void setUserInput(const Data & data) {
if (!isSafe(this))
return postCall(this, &ASTWorker::setUserInput, data);
QThread::msleep(1); // emulate processing user data
}
/// Thread-safe
Q_SLOT void evaluate() {
if (!isSafe(this))
return postCall(this, &ASTWorker::evaluate, data);
evaluateImpl();
}
};
相关文章:
- 如何在长时间运行的方法中等待信号?
- 如何避免等待信号已经发送的pthread_cond_t
- 如何让一个线程继续,而另一个线程正在等待C++中的信号量
- QT:使用Qeventloop等待信号,如果信号发射得太早该怎么办
- Qt :等待来自函数的信号的最佳方法
- C++ 使用信号量而不是忙于等待
- 在POSIX中,我可以保存信号以供调用条件等待的其他线程使用吗.(这些线程来自同一进程)
- 在发出等待条件变量的信号后,线程何时获取锁?是什么决定了它
- Windows高速模式(C++):等待信号量(WaitForSingleObjectEx):失败,访问被拒绝[部分解决]
- 如果我们不等待就发出信号量会发生什么
- 如何正确等待线程中的信号
- 进程等待另一进程终止时的信号处理
- 如何用WaitForSingleObject发出等待文件HANDLE的信号
- 如何构造用于等待来自不相关类的两个信号对象的代码
- 信号量未能等待,原因"Resource temporarily unavailable"
- Qt5中存在哪些同步原语,允许我在单个线程中等待信号到达
- 当线程等待互斥锁时捕获的信号
- 尝试等待信号量时出错
- Qt5:如何在线程中等待信号
- 我可以在等待/信号量中切换测试和修改部分吗?