gpt4 book ai didi

c++ - 中断到达时如何退出 sleep()?

转载 作者:行者123 更新时间:2023-12-02 10:03:16 24 4
gpt4 key购买 nike

我正在寻找一种在用户中断到达时退出 sleep 的方法。重要的是退出 sleep 而不是这样做:中断 sleep ,进行 ISR 处理,然后回到 sleep 状态 - 这就是我正在寻找的解决方案。
我正在 C++ 中寻找类似的东西 - C 中的等价物甚至更好:

void *timer_thread(void *dummy)
{
while(1)
{
// Check if some callbacks are to be given
// when all are given, Determine x duration to sleep

try
{
sleep(x);
}
except(/* the except block should hit ONLY when an interrupt arrives,
that too only when sleep() is executed. It's OK to delay
interrupt until the sleep is beginning execution */)
{
//Do something else
}
}
}
到达的中断主要会告诉计时器线程应该减少 sleep 时间以更早地提供回调。但是不管用例如何,我只需要在中断到达时以某种方式退出 sleep 。我只是找不到有关如何执行此操作的信息。
PS:如果在 sleep 未发生时发生中断,则可以丢弃/NOP 中断
这是在 Windows 10 (C/C++) 上的 Cygwin gcc v9.3.0 上。我不需要代码是可移植的,所以任何特定于平台的解决方案也可以。
如果有其他与此工作类似的解决方案(不使用 sleep() 和中断),欢迎听到。我只是在寻找一种不涉及投票的方式。

最佳答案

为了等待某个时间或某个事件,我会使用 std::mutex 的组合。和 std::condition_variable特别是 std::condition_variable::wait_for()等待超时或某事的信号变化。

用于演示的最小示例程序:

#include <atomic>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;

// a thread-shared flag to signal exit
std::atomic<bool> exitThread = false;

// a mutex to sync. inter-thread communication
std::mutex mtxAlert;
// a condition variable to signal changed data
std::condition_variable sigAlert;
// the data of inter-thread communication
bool alert = false;

void timerThread()
{
// the timeout for timer thread
auto timeout = 100ms;
// runtime loop
while (!exitThread) {
// lock mutex (preparation to wait in cond. var.)
std::unique_lock<std::mutex> lock(mtxAlert);
// unlock mutex and wait for timeout or signaled alert
sigAlert.wait_for(lock, timeout, []() { return alert || exitThread; });
// mutex is locked again
// check why wait_for() exited
if (exitThread) {
std::cout << "Timer thread exiting...\n";
return;
} else if (alert) {
std::cout << "Timer was interrupted due to alert.\n";
alert = false;
} else {
std::cout << "Timer achieved time-out.\n";
}
}
}

int main()
{
std::thread threadWait(&timerThread);
// wait a bit
std::cout << "main(): Waiting 300ms...\n";
std::this_thread::sleep_for(300ms);
// sim. interrupt
std::cout << "main(): Sim. interrupt.\n";
{ std::lock_guard<std::mutex> lock(mtxAlert);
alert = true;
}
sigAlert.notify_all();
// wait a bit
std::cout << "main(): Waiting 50 ms...\n";
std::this_thread::sleep_for(50ms);
// sim. interrupt
std::cout << "main(): Sim. interrupt.\n";
{ std::lock_guard<std::mutex> lock(mtxAlert);
alert = true;
}
sigAlert.notify_all();
// wait a bit
std::cout << "main(): Waiting 50 ms...\n";
std::this_thread::sleep_for(50ms);
// exiting application
exitThread = true;
sigAlert.notify_all();
threadWait.join();
// done
std::cout << "Done.\n";
}

输出:

main(): Waiting 300ms...
Timer achieved time-out.
Timer achieved time-out.
main(): Sim. interrupt.
main(): Waiting 50 ms...
Timer was interrupted due to alert.
main(): Sim. interrupt.
main(): Waiting 50 ms...
Timer was interrupted due to alert.
Timer thread exiting...
Done.

Live Demo on coliru

OP 根据评论声称此示例在 cygwin 上没有正确编译.我在我这边尝试过,可以确认我修复的一些小问题:
  • 失踪 #include <mutex>已添加
  • std::atomic<bool> exitThread = false; 的初始化变成
    std::atomic<bool> exitThread(false);

    我用 g++ 编译时得到了这个以及 g++ -std=c++14 . (似乎 -std=c++14 是我的 g++ 的默认值。)

    当我使用 g++ -std=c++17相反,我没有收到任何投诉。我坚信这与copy-elision有关其中g++适用于 -std=c++17但不是之前。

  • 但是,这是我的示例 session ,在 cygwin64 中对我的 Windows 10 笔记本电脑上的代码进行了稍微审查。 :

    $ g++ --version
    g++ (GCC) 7.4.0

    $

    $ cat >testCondVar.cc <<'EOF'
    > #include <atomic>
    > #include <condition_variable>
    > #include <iostream>
    > #include <mutex>
    > #include <thread>
    > #include <chrono>
    > using namespace std::chrono_literals;
    >
    > // a thread-shared flag to signal exit
    > std::atomic<bool> exitThread(false);
    >
    > // a mutex to sync. inter-thread communication
    > std::mutex mtxAlert;
    > // a condition variable to signal changed data
    > std::condition_variable sigAlert;
    > // the data of inter-thread communication
    > bool alert = false;
    >
    > void timerThread()
    > {
    > // the timeout for timer thread
    > auto timeout = 100ms;
    > // runtime loop
    > while (!exitThread) {
    > // lock mutex (preparation to wait in cond. var.)
    > std::unique_lock<std::mutex> lock(mtxAlert);
    > // unlock mutex and wait for timeout or signaled alert
    > sigAlert.wait_for(lock, timeout, []() { return alert || exitThread; });
    > // mutex is locked again
    > // check why wait_for() exited
    > if (exitThread) {
    > std::cout << "Timer thread exiting...\n";
    > return;
    > } else if (alert) {
    > std::cout << "Timer was interrupted due to alert.\n";
    > alert = false;
    > } else {
    > std::cout << "Timer achieved time-out.\n";
    > }
    > }
    > }
    >
    > int main()
    > {
    > std::thread threadWait(&timerThread);
    > // wait a bit
    > std::cout << "main(): Waiting 300ms...\n";
    > std::this_thread::sleep_for(300ms);
    > // sim. interrupt
    > std::cout << "main(): Sim. interrupt.\n";
    > { std::lock_guard<std::mutex> lock(mtxAlert);
    > alert = true;
    > }
    > sigAlert.notify_all();
    > // wait a bit
    > std::cout << "main(): Waiting 50 ms...\n";
    > std::this_thread::sleep_for(50ms);
    > // sim. interrupt
    > std::cout << "main(): Sim. interrupt.\n";
    > { std::lock_guard<std::mutex> lock(mtxAlert);
    > alert = true;
    > }
    > sigAlert.notify_all();
    > // wait a bit
    > std::cout << "main(): Waiting 50 ms...\n";
    > std::this_thread::sleep_for(50ms);
    > // exiting application
    > exitThread = true;
    > sigAlert.notify_all();
    > threadWait.join();
    > // done
    > std::cout << "Done.\n";
    > }
    > EOF

    $

    编译并启动:

    $ g++ -std=c++14 -o testCondVar testCondVar.cc

    $ ./testCondVar
    main(): Waiting 300ms...
    Timer achieved time-out.
    Timer achieved time-out.
    main(): Sim. interrupt.
    main(): Waiting 50 ms...
    Timer was interrupted due to alert.
    main(): Sim. interrupt.
    main(): Waiting 50 ms...
    Timer was interrupted due to alert.
    Timer thread exiting...
    Done.

    $

    注:

    此示例至少需要 C++14 的唯一原因是使用了 std::chrono_literals这使得可以使用例如 300ms .

    std::chrono_literals ,这可以写成 std::chrono::milliseconds(300) (这无疑不太方便)。全部更换 std::chrono_literals分别,我能够使用 -std=c++11 编译和运行示例。以及。

    关于c++ - 中断到达时如何退出 sleep()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61494611/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com