C++ 编写自定义睡眠的正确方法
我目前正在为模拟器编写代码,以便与ROS时间同步 从本质上讲,问题变成了“写一个根据ROS时间缩放的get_时间和睡眠”?这样做将不允许更改代码库,只需要链接到定制的get_time和sleep<代码>获取时间似乎工作得很好;然而,我一直很难让睡眠准确地运行 我目前的设计是这样的(代码附在底部):C++ 编写自定义睡眠的正确方法,c++,optimization,C++,Optimization,我目前正在为模拟器编写代码,以便与ROS时间同步 从本质上讲,问题变成了“写一个根据ROS时间缩放的get_时间和睡眠”?这样做将不允许更改代码库,只需要链接到定制的get_time和sleep获取时间似乎工作得很好;然而,我一直很难让睡眠准确地运行 我目前的设计是这样的(代码附在底部): 线程调用睡眠 Sleep将把解锁此线程的时间(当前时间+睡眠时间)添加到优先级队列中,然后等待条件变量 一个单独的线程(我们称之为watcher)将不断循环并检查队列的顶部;如果prio队列的顶部>当前时间,
- 通过使用条件变量数组并根据时间分配它们,减少不必要的notify_all调用的数量,如:(ms/100)%256。他们的想法是,在一起的时间将共享同一份简历,因为他们很可能从“通知所有人”中醒来。这使得性能更差
- 保持线程和优先级队列推送等,但使用usleep。我发现usleep将使其工作得更好,这可能意味着互斥、锁定和推/弹出操作不会造成明显的延迟,这意味着它必须位于条件变量部分
代码: 监视程序(在启动时运行)
void-watcher()
{
while(true)
{
usleep(1);
{
std::lock_guard lk(m_队列);
if(prio_queue.empty())
继续;
if(get_time_in_ms()>=prio_queue.top())
{
cv.通知所有人();
prio_queue.pop();
}
}
}
}
睡眠
void sleep(int-ms)
{
int wakeup=get_time_in_ms()+ms;
{
std::lock_guard lk(m_队列);
优先级队列推送(唤醒);
}
std::唯一锁定lk(m_时间);
cv.wait(lk,[wakeup]{return get_time_in_ms()>=wakeup;});
lk.unlock();
}
任何帮助都将不胜感激 睡眠时间只保证至少是你要求的时间量。从来都不能保证精确的睡眠。为了减少错误,您需要在RTOS上运行,但我不相信有任何系统能够准确、一致地保持精确的睡眠。也许引入1pps信号+中断是一个好方法,但这会增加一些恼人的硬件+软件开销。但我确实知道,操作系统的usleep比这个版本要好得多。它不需要完美;正如操作系统所做的一样,它的睡眠时间只保证至少是您请求的时间量。从来都不能保证精确的睡眠。为了减少错误,您需要在RTOS上运行,但我不相信有任何系统能够准确、一致地保持精确的睡眠。也许引入1pps信号+中断是一个好方法,但这会增加一些恼人的硬件+软件开销。但我确实知道,操作系统的usleep比这个版本要好得多。它不需要完美;就像操作系统如何做到这一点一样好
void watcher()
{
while (true)
{
usleep(1);
{
std::lock_guard<std::mutex> lk(m_queue);
if (prio_queue.empty())
continue;
if (get_time_in_ms() >= prio_queue.top())
{
cv.notify_all();
prio_queue.pop();
}
}
}
}
void sleep(int ms)
{
int wakeup = get_time_in_ms() + ms;
{
std::lock_guard<std::mutex> lk(m_queue);
prio_queue.push(wakeup);
}
std::unique_lock<std::mutex> lk(m_time);
cv.wait(lk, [wakeup] {return get_time_in_ms() >= wakeup;});
lk.unlock();
}