c++ - 通过信号中断睡眠
问题描述
我想编写一个 C++ 程序,它应该等待一个 linux 信号(毫秒分辨率),但我找不到实现这一点的可能性。
以下测试代码应在 500 毫秒后终止,但事实并非如此。
#include <iostream>
#include <csignal>
#include <unistd.h>
#include <chrono>
#include <future>
using namespace std::chrono_literals;
extern "C" void handler(int s) {
}
int main() {
std::signal(SIGUSR1, handler);
bool started = false;
auto f = std::async(std::launch::async, [&] {
auto start = std::chrono::high_resolution_clock::now();
started = true;
//usleep(1000000);
sleep(1);
//std::this_thread::sleep_for(1s);
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start).count() << "ms";
});
std::this_thread::sleep_for(500ms);
std::raise(SIGUSR1);
}
有人知道如何解决这种行为吗?
解决方案
执行您的信号处理程序后,程序将返回其正常操作。睡眠不会终止,因为它与处理信号的线程在不同的线程中作为注释中的明确注释。
相反,这个答案是 C/C++: How to exit sleep() when an interrupt到达?建议使用互斥锁来阻止操作。这更容易try_lock_for
还显示线程 ID(显示它们是不同的线程),这可能是:
#include <iostream>
#include <csignal>
#include <unistd.h>
#include <chrono>
#include <future>
using namespace std::chrono_literals;
std::timed_mutex mtx;
extern "C" void handler(int s) {
std::cout << std::this_thread::get_id() << " signal handler"
<< std::endl;
mtx.unlock();
}
int main() {
std::signal(SIGUSR1, handler);
auto start_outer = std::chrono::high_resolution_clock::now();
mtx.lock();
auto f = std::async(std::launch::async, [&] {
auto start = std::chrono::high_resolution_clock::now();
mtx.try_lock_for(std::chrono::milliseconds(1000));
std::cout << std::this_thread::get_id() << " "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start).count() << "ms"
<< std::endl;
});
std::this_thread::sleep_for(500ms);
std::cout << std::this_thread::get_id() << " "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start_outer).count() << "ms"
<< std::endl;
std::raise(SIGUSR1);
}
构建、运行、输出
% g++ -std=c++17 test.cpp && ./a.out
0x112cb9dc0 506ms
0x112cb9dc0 signal handler
0x700009e86000 506ms
推荐阅读
- sql - ROW_NUMBER Oracle - 奇怪的行为(添加行)
- java - 用户存储 SPI 中的 Keycloak 自定义异常
- c - 成对短字符串段比较问题的快速实现
- javascript - 如何随机使地图中的图像一张一张地出现淡入淡出?
- c++ - 显示 C++ 格式的日期
- jenkins - 与 Jenkins Crumb 值的差异
- react-native - Xcode Build failed 如果我将上传调试符号添加到哨兵脚本
- c# - 使用 c# 连接到 Azure VM 的 SQL DB
- php - IIS/PHP 未传递(或传递不正确的)NTLM 用户信息
- python - 腌制的人物看起来比原来的大