支持实时和非实时模式的程序

时间:2012-04-07 19:34:39

标签: c++ c++11

我正在尝试转换现有程序,以便在(自行开发的)现有时间类中使用C ++ 11中的新时间工具。对于实时处理,很清楚如何将C ++ 11功能映射到自行开发的时间类中。目前还不太清楚如何使用C ++ 11计时时间设备来支持非实时模式(例如,“以尽可能快的速度运行”,“以四分之一速度运行模式运行”等) 。)本土班级支持的。这是通过定义特殊的clock来实现的,这些MessageQueue::poll( Seconds( 1 ) ); 正确地将墙上时间映射到“回放”速度吗?任何帮助表示赞赏和一个例子都很棒。

例如,我将转换的代码具有诸如

之类的结构
sleep( Minutes( 2 ) );

Seconds

MinutesMessageQueue::poll( PlaybackSpeed * Seconds( 1 ) ); 对象知道程序运行的速度,以避免在整个地方使用乘法器或转换函数,如

MessageQueue::poll( PlaybackSpeed( Seconds( 1 ) ) );

std::chrono::duration

我希望可能通过提供自定义std::chrono::time_pointclock和{{1}}获得相同的行为。

2 个答案:

答案 0 :(得分:2)

创建自己的时钟是否足够取决于您使用创建的持续时间的方式。例如,如果你想以半速运行但在某个地方叫:

std::this_thread::sleep_for(std::chrono::minutes(2));

持续时间不会调整。相反,您需要使用sleep_until并提供使用“慢”时钟的时间点。但制作一个运行缓慢的时钟非常简单:

template<typename Clock,int slowness>
struct slow_clock {
    using rep = typename Clock::rep;
    using period = typename Clock::period;
    using duration = typename Clock::duration;
    using time_point = std::chrono::time_point<slow_clock>;

    constexpr static bool is_steady = Clock::is_steady;

    static time_point now() {
        return time_point(start_time.time_since_epoch() + ((Clock::now() - start_time)/slowness));
    }

    static const typename Clock::time_point start_time;
};

template<typename Clock,int slowness>
const typename Clock::time_point
slow_clock<Clock,slowness>::start_time = Clock::now();

从now()返回的time_points似乎相对于你给它的时钟以较慢的速度前进。例如,这是一个程序,所以你可以通过以下方式慢慢观察纳秒:

int main() {
    using Clock = slow_clock<std::chrono::high_resolution_clock,500000000>;
    for(int i=0;i<10;++i) {
        std::this_thread::sleep_until(Clock::now()
                                      + std::chrono::nanoseconds(1));
        std::cout << "tick\n";
    }
}

您实现的所有功能(如MessageQueue::poll())可能需要根据全局时钟类型定义来实现。

当然,这与程序实际运行的速度无关,除非你根据它们减慢程序的速度。超时的函数需要更长的时间,sleep_until将需要更长的时间,但是未来等待某个时间点的操作看起来会更快。

// appears to run a million times faster than normal according to (finish-start)
auto start = slow_clock<steady_clock,1000000>::now();
do_slow_operation();
auto finish = slow_clock<steady_clock,1000000>::now();

答案 1 :(得分:0)

对于这种情况:

MessageQueue::poll( Seconds( 1 ) );

如果您只是让MessageQueue了解&#34;速度&#34;那么您可以轻松使用标准时间类。它应该运行在。如果你想以半速运行,只需调用MessageQueue::setPlaybackSpeed(0.5)之类的东西,并让队列在有人给它一定时间时使用该因子。

至于此:

sleep( Minutes( 2 ) );

你的旧代码在做什么?我想Minutes()创建的任何对象都有一个隐式转换运算符到int,返回秒数?这对我来说似乎太神奇了 - 最好只在你的MessageQueue或其他类上创建一个sleep()方法,然后你可以使用与上面相同的解决方案。