通过信号中断睡眠 我想编写一个C++程序,它应该等待Linux信号(毫秒分辨率),但我无法找到实现这个目的的可能。
以下测试代码应在500毫秒后终止,但不会终止通过信号中断睡眠 我想编写一个C++程序,它应该等待Linux信号(毫秒分辨率),但我无法找到实现这个目的的可能。,c++,linux,c++17,system-calls,usleep,C++,Linux,C++17,System Calls,Usleep,以下测试代码应在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() {
#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);
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std::chrono_文本;
外部“C”无效处理程序(int s){
}
int main(){
std::信号(SIGUSR1,处理器);
bool start=false;
自动f=std::async(std::launch::async,[&]{
自动启动=标准::时钟::高分辨率时钟::现在();
开始=真;
//美国LEEP(1000000);
睡眠(1);
//std::this_线程::sleep_for(1s);
std::cout程序在执行信号处理程序后返回正常操作。睡眠不会终止,因为它与注释中处理信号的线程不同
相反,这个答案建议使用互斥来阻止操作
同时显示线程ID(显示它们是不同的线程),可以改为:
#包括
#包括
#包括
#包括
#包括
使用名称空间std::chrono_文本;
std::timed_mutex mtx;
外部“C”无效处理程序(int s){
std::cout程序在执行信号处理程序后返回正常操作。睡眠不会终止,因为它与注释中处理信号的线程不同
相反,这个答案建议使用互斥来阻止操作
同时显示线程ID(显示它们是不同的线程),可以改为:
#包括
#包括
#包括
#包括
#包括
使用名称空间std::chrono_文本;
std::timed_mutex mtx;
外部“C”无效处理程序(int s){
有了ti7和user4581301的想法,我终于找到了一个解决方案
在signal_处理程序中使用互斥体,但仅限于允许的系统调用集,我使用信号量
sem_t *sem_g = nullptr;
extern "C" void handler(int s) {
if (sem_g)
sem_post(sem_g);
}
int main() {
sem_t sem = {};
sem_init(&sem, 0, 0);
sem_g = &sem;
std::signal(SIGUSR1, handler);
auto f = std::async(std::launch::async, [&] {
auto start = std::chrono::high_resolution_clock::now();
auto time_point = std::chrono::system_clock::now() + 10s;
auto duration = time_point.time_since_epoch();
auto secs = std::chrono::duration_cast<std::chrono::seconds>(duration);
auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - secs);
timespec t{secs.count(), nanos.count()};
auto r = sem_timedwait(&sem, &t);
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);
}
sem_t*sem_g=nullptr;
外部“C”无效处理程序(int s){
if(sem_g)
sem_post(sem_g);
}
int main(){
sem_t sem={};
sem_init(&sem,0,0);
sem_g=&sem;
std::信号(SIGUSR1,处理器);
自动f=std::async(std::launch::async,[&]{
自动启动=标准::时钟::高分辨率时钟::现在();
自动时间点=标准::计时::系统时钟::现在()+10s;
自动持续时间=时间\u点。自\u epoch()起的时间\u;
自动秒=std::chrono::duration\u cast(持续时间);
自动nanos=std::chrono::持续时间(持续时间-秒);
timespec t{secs.count(),nanos.count()};
自动r=sem\u timedwait(&sem,&t);
有了ti7和user4581301的想法,我终于找到了一个解决方案
在signal_处理程序中使用互斥体,但仅限于允许的系统调用集,我使用信号量
sem_t *sem_g = nullptr;
extern "C" void handler(int s) {
if (sem_g)
sem_post(sem_g);
}
int main() {
sem_t sem = {};
sem_init(&sem, 0, 0);
sem_g = &sem;
std::signal(SIGUSR1, handler);
auto f = std::async(std::launch::async, [&] {
auto start = std::chrono::high_resolution_clock::now();
auto time_point = std::chrono::system_clock::now() + 10s;
auto duration = time_point.time_since_epoch();
auto secs = std::chrono::duration_cast<std::chrono::seconds>(duration);
auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - secs);
timespec t{secs.count(), nanos.count()};
auto r = sem_timedwait(&sem, &t);
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);
}
sem_t*sem_g=nullptr;
外部“C”无效处理程序(int s){
if(sem_g)
sem_post(sem_g);
}
int main(){
sem_t sem={};
sem_init(&sem,0,0);
sem_g=&sem;
std::信号(SIGUSR1,处理器);
自动f=std::async(std::launch::async,[&]{
自动启动=标准::时钟::高分辨率时钟::现在();
自动时间点=标准::计时::系统时钟::现在()+10s;
自动持续时间=时间\u点。自\u epoch()起的时间\u;
自动秒=std::chrono::duration\u cast(持续时间);
自动nanos=std::chrono::持续时间(持续时间-秒);
timespec t{secs.count(),nanos.count()};
自动r=sem\u timedwait(&sem,&t);
这是正确的,但是睡眠应该被信号中止,这样它才能完成faster@gerum低级系统调用可能会被信号中断,但
的高级sleep\u不会中断。例如,您可以看到libstdc++的实现处理EINTR
并在剩余时间内继续休眠LD更倾向于不使用未定义的行为,我在代码中看到了两个可能的UB源。首先,您在MealAlxHand中解锁互斥体,但我不确定它是否与主线程相同,必须解锁互斥体。在信号处理程序中使用互斥体,但我不认为,在外部“C”中使用C++类。函数定义得很好。@MilesBudnek是的,我认为这个线程sleep只是为了完整性而添加的,我真的不希望它能工作,但是带有sleep或usleep的版本应该可以工作。旁注:在信号处理程序中有一些危险的东西。@gerum只是从不同的上下文中锁定解锁,但是除了在信号处理程序,至少在*nix系统中是这样。这是正确的,但是睡眠应该被信号中止,这样它才能完成faster@gerum低级系统调用可能会被信号中断,但
的高级sleep\u不会中断。例如,您可以看到libstdc++的实现处理EINTR
并继续执行在剩下的时间里,我不想使用未定义的行为,我在代码中看到了UB的两个可能来源。首先,你在signal_处理程序中解锁互斥体,但我不确定这是否与主线程相同,在主线程中,你必须解锁互斥体。你在signal处理程序中使用互斥体,但我不认为,使用外部C语言中的C++类函数定义得很好。@MilesBudnek是的,我认为这个线程sleep只是为了完整性而添加的,我真的不希望它能工作,但是带有sleep或usleep的版本应该可以工作。旁注:在信号处理程序中有一些危险的东西。@gerum只是从不同的上下文中锁定解锁,但是除了在信号处理程序,至少在*nix系统中是这样。使用信号和计时器文件描述符很容易做到这一点,但这是一个相当高级的主题。从Linux手册页面开始,了解timerfd和signalfd系统调用,然后从那里开始工作。这是吗