我有以下问题:我们有一个用ros_control实现的控制器,它运行在一个实时的Xenomai linux补丁系统上。通过迭代调用更新函数来执行控制循环。我需要传达控制器的一些内部状态,为此我使用了麻省理工学院开发的LCM。不管LCM的内部行为如何,发布方法破坏了实时性,因此我在C 11中实现了一个在独立线程上运行的发布循环。但是如果我不把第二个线程和控制器同步,这个循环就会以无限的频率发布。因此我也使用了条件变量。
以下是控制器的一个示例:
MyClass mc;
// This is called just once
void init(){
mc.init();
}
// Control loop function (e.g., called every 5 ms in RT)
void update(const ros::Time& time, const ros::Duration& period) {
double value = time.toSec();
mc.setValue(value);
}
对于尝试发布的类:
double myvalue;
std::mutex mutex;
std::condition_variable cond;
bool go = true;
void MyClass::init(){
std::thread thread(&MyClass::body, this);
}
void MyClass::setValue(double value){
myvalue = value;
{
std::lock_guard<std::mutex> lk(mutex);
go = true;
}
cond.notify_one();
}
void MyClass::body() {
while(true) {
std::unique_lock<std::mutex>lk(mutex);
cond.wait(lk, [this] {return go;});
publish(myvalue); // the dangerous call
go = false;
lk.unlock();
}
}
此代码产生模式切换(即实时中断)。可能是因为条件变量的锁定,我用它来同步辅助线程与主控制器,并与线程争用。如果我这样做:
void MyClass::body() {
while(true) {
if(go){
publish(myvalue);
go = false;
}
}
}
void MyClass::setValue(double value){
myvalue = value;
go = true;
}
我不会产生模式切换,但这也不安全,最重要的是,我会忙于等待第二个线程。
有没有一种方法可以在主线程和辅助线程之间实现非阻塞同步(即只有在调用setValue
时才让body
执行某些操作),这也是非繁忙的等待?
这并不完美,但它应该减少您的繁忙等待频率,只是偶尔失去响应能力。
这个想法是在通过原子传递消息时使用裸条件变量唤醒。
template<class T>
struct non_blocking_poke {
std::atomic<T> message;
std::atomic<bool> active;
std::mutex m;
std::condition_variable v;
void poke(T t) {
message = t;
active = true;
v.notify_one();
}
template<class Rep, class Period>
T wait_for_poke(const std::chrono::duration<Rep, Period>& busy_time) {
std::unique_lock<std::mutex> l(m);
while( !v.wait_for(l, busy_time, [&]{ return active; } ))
{}
active = false;
return message;
}
};
等待线程每隔busy_time
唤醒一次,以查看它是否错过了一条消息。但是,它通常会比这更快地收到消息(存在一个争用条件,即它错过了一条消息)。此外,可以发送多条消息,而无需缓解程序获取它们。但是,如果发送了一条消息,则在大约 1 秒内,接收方将收到该消息或稍后的消息。
non_blocking_poke<double> poker;
// in realtime thread:
poker.poke(3.14);
// in non-realtime thread:
while(true) {
using namespace std::literals::chrono_literals;
double d = poker.wait_for_poke( 1s );
std::cout << d << '\n';
}
在工业质量解决方案中,您还需要中止标志或消息来停止循环。
使用无锁数据结构。
在你这里的情况下,你甚至不需要一个数据结构,只需使用一个原子就可以了
。无需锁。您可以考虑使用信号量而不是条件变量来避免现在未使用的锁。如果你需要一个信号量来避免使用锁,你最终会使用你的基本操作系统信号量,而不是C 11,因为C 11甚至没有它们。
问题内容: 我遇到的问题是,有时我启动的线程在调用它之前就完成了。看来这使我的程序等待不再发生的事情()。如何确保不等待线程完成? 问题答案: 如果您阅读JavaDocs for Thread,它将告诉您 永远不要在Thread对象上使用。您应该使用join()
下面的代码允许服务器等待客户端连接到(已经绑定的)套接字。它在客户端连接到套接字时终止,或者在“server_run”取值0时终止:这允许代码的其他部分在合适的时候关闭服务器。 根据对另一个帖子(C:non blocking sockets with timeout:how to check if connection request was made?)的回答和评论,这不是一种方法,因为它涉及到
问题内容: 我想知道WebDriver等待超时和隐式等待超时之间的技术差异。 问题答案: 如文档中所述: 在内部设置将用于所有连续搜索的超时。如果找不到该元素,它将尝试在指定的时间内反复查找该元素。它仅执行此操作,不能强制执行其他任何操作- 它等待元素显示。 ,或者只是您用于特定搜索的一次计时器。它具有更大的可扩展性,意味着您可以将其设置为等待可能需要的任何条件。通常,您可以使用一些预构建的元素来
嗨,我正在做一个项目,我已经达到了我非常困的部分。我试图寻找方法来学习如何在繁忙的等待中编写 while 循环,但我没有找到任何东西,我的代码只是作为无限循环运行。有人可以帮助我解释一个繁忙的等待循环应该如何工作,并帮助我打破这个无限循环吗? 该项目希望做到以下几点:早上,学生醒来后(这需要一段随机的时间),他会去洗手间为新的上学日做准备。如果浴室已经客满,学生需要Rest一下(使用yield()
线程状态WAIT和线程状态BLOCKED有什么区别? 线。国家文件: Blocked 等待监视器锁而被阻塞的线程处于这种状态。 等待 无限期等待另一个线程执行特定操作的线程处于此状态 这不能向我解释差异。
问题内容: 我找不到如何测量线程等待锁定的时间。我必须确定一个线程是否正在等待锁定超过1秒,如果需要,则运行另一个线程。谢谢! 问题答案: 试试这个: