我正在做一个需要1ms睡眠的程序。为了产生长度~1ms的硬件脉冲,使用了睡眠。
我正在使用下面的代码来睡眠
void usleep(__int64 usec)
{
HANDLE timer;
LARGE_INTEGER ft;
ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
timer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}取自这里
当我在Intel i7上使用上面的代码(使用Embarcaderos i7编译器)时,通过1000 ( 1ms ),我就可以使用波科时间戳函数来测量睡眠时间,达到大约1ms。代码本身在线程中执行。
代码如下所示:
mDebugFile << std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 0 << "\n";
setHigh(false);
mDebugFile << std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 1 << "\n";
usleep(1000);
mDebugFile << std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 1 << "\n";
setLow(false);
mDebugFile << std::setprecision (17) << mPulseEventTime.elapsed()/1000.0 << "\t" << 0 << "\n";其中mDebugFile是fstream对象,setLow/setHigh是对硬件的调用。
但是,当在上执行相同的代码( Xeon )时,睡眠量约为10 ms。假设Poco的定时函数给出了适当的时间,当要求1ms时,10 ms是相当大的。
还有其他方法可以让你在1ms内获得可靠的睡眠吗?可以修改Windows操作系统以提供更可靠的睡眠吗?
我无法访问boost或以上的C++11功能。
发布于 2020-06-11 17:23:03
Windows并不是一个实时的操作系统,因此在用户代码中获得超级精确的睡眠时间是永远无法保证的。有很多事情在起作用。
在Windows上增加默认计时器解析的API有两个: NtSetTimerResolution (正式无文档)或timeBeginPeriod。如果机器没有超载,您可以使用基本方法(例如睡眠),在用户代码中获得接近1ms的间隔。
但是很多节目都是浪费能源滥用这些原料药。(如果你在一台机器上看到1毫秒的分辨率,很可能是因为某个程序已经提高了计时器分辨率。)长期以来,这一直被认为是不好的做法。定时器分辨率是一个系统范围的设置,因此它会影响机器上运行的一切.如果必须增加分辨率,请只在需要时这样做,并确保在完成后立即恢复默认值。
如果您需要更高的精度,我相信您需要做一个内核模式的驱动程序,但我没有这方面的经验。在某种程度上,Windows增加了一个音频堆栈,以保证延迟20 us或更少。如果我没记错的话,那就需要内核模式的恶作剧。
您可以考虑使用微控制器(例如,Arduino)来生成硬件信号,并让Windows程序通过串行接口向其发送命令。
https://stackoverflow.com/questions/62273909
复制相似问题