在 windows 每 100 微秒生成一次中断
Generating interrupt each 100 microsecond on windows
我想在 windows 上每 100 微秒生成一次中断。实际上我无法在 windows 上执行此操作,因为 windows 不能保证中断少于 500 微秒。所以,我生成了 2 个线程。其中一个用于定时器计数器(查询性能计数器),另一个线程是实际工作。当计时器计数器为 100 微秒时,它会更改另一个线程(实际工作)的状态。但是我有竞争条件的问题,因为我不希望线程互相等待,它们必须总是 运行。所以实际上我需要中断。我如何使用 C++ 在 windows 上编写如此快速的中断?
为了避免在这么短的时间内让两个线程进行通信 windows,我将工作和计时器都放在一个线程的循环中。
- 在线程启动时对时钟进行采样,并在每个循环中增加 100μs。
- 睡眠到计算的时间。通常情况下,人们会使用
std::this_thread::sleep_until
来做这样的睡眠,但在这种情况下,当小睡时间如此短时,它往往变得有点太不准确了,所以我建议在一个紧密的循环中忙等待,只检查时间.
- 做你的工作。
在此示例中,工作线程运行了 10 秒,但没有做任何实际工作。在我的机器上,我可以在整个循环开始花费超过 100 微秒的时间之前,在您应该完成工作的插槽中添加由 ~3000 个添加组成的工作,因此您最好快速完成您的目标。
示例:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
static std::atomic<bool> running = true;
using myclock = std::chrono::steady_clock;
void worker() {
int loops = 0;
auto sleeper = myclock::now();
while(running) {
++loops; // count loops to check that it's good enough afterwards
// add 100us to the sleeper time_point
sleeper += 100us;
// busy-wait until it's time to do some work
while(myclock::now() < sleeper);
// do your work here
}
std::cout << loops << " (should be ~100000)\n";
}
int main() {
auto th = std::thread(worker);
// let the thread work for 10 seconds
std::this_thread::sleep_for(10s);
running = false;
th.join();
}
可能的输出:
99996 (should be ~100000)
启动线程需要几个时钟周期,因此不必担心循环数未完全达到目标。将线程运行时间加倍,您仍应保持接近目标循环数。重要的是一旦启动 漂亮 好(但不是 实时-好)运行.
我想在 windows 上每 100 微秒生成一次中断。实际上我无法在 windows 上执行此操作,因为 windows 不能保证中断少于 500 微秒。所以,我生成了 2 个线程。其中一个用于定时器计数器(查询性能计数器),另一个线程是实际工作。当计时器计数器为 100 微秒时,它会更改另一个线程(实际工作)的状态。但是我有竞争条件的问题,因为我不希望线程互相等待,它们必须总是 运行。所以实际上我需要中断。我如何使用 C++ 在 windows 上编写如此快速的中断?
为了避免在这么短的时间内让两个线程进行通信 windows,我将工作和计时器都放在一个线程的循环中。
- 在线程启动时对时钟进行采样,并在每个循环中增加 100μs。
- 睡眠到计算的时间。通常情况下,人们会使用
std::this_thread::sleep_until
来做这样的睡眠,但在这种情况下,当小睡时间如此短时,它往往变得有点太不准确了,所以我建议在一个紧密的循环中忙等待,只检查时间. - 做你的工作。
在此示例中,工作线程运行了 10 秒,但没有做任何实际工作。在我的机器上,我可以在整个循环开始花费超过 100 微秒的时间之前,在您应该完成工作的插槽中添加由 ~3000 个添加组成的工作,因此您最好快速完成您的目标。
示例:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
static std::atomic<bool> running = true;
using myclock = std::chrono::steady_clock;
void worker() {
int loops = 0;
auto sleeper = myclock::now();
while(running) {
++loops; // count loops to check that it's good enough afterwards
// add 100us to the sleeper time_point
sleeper += 100us;
// busy-wait until it's time to do some work
while(myclock::now() < sleeper);
// do your work here
}
std::cout << loops << " (should be ~100000)\n";
}
int main() {
auto th = std::thread(worker);
// let the thread work for 10 seconds
std::this_thread::sleep_for(10s);
running = false;
th.join();
}
可能的输出:
99996 (should be ~100000)
启动线程需要几个时钟周期,因此不必担心循环数未完全达到目标。将线程运行时间加倍,您仍应保持接近目标循环数。重要的是一旦启动 漂亮 好(但不是 实时-好)运行.