我正在使用 timer_create 函数和 SIGEV_THREAD 参数创建 Linux 定时器。
有时,在我取消并删除定时器后,回调仍会被调用。这会导致段错误,因为它尝试访问已删除的资源。
Linux 手册上说:
“timer_delete() 函数删除 ID 为 timerid 的定时器。如果在此调用时定时器已启动,则在删除前先将其停止。任何由已删除的定时器生成的待处理信号的处理未指定。”
基本上这意味着我不知道回调是否会被调用,也没有方法来取消它或在清理资源之前强制挂起信号传递。请参见链接:http://man7.org/linux/man-pages/man2/timer_delete.2.html
如果timer_wrapper超出范围,我希望回调不再被调用,然而有时候它仍会被调用,根据手册,这是期望的行为。如何解决这个问题?
有时,在我取消并删除定时器后,回调仍会被调用。这会导致段错误,因为它尝试访问已删除的资源。
Linux 手册上说:
“timer_delete() 函数删除 ID 为 timerid 的定时器。如果在此调用时定时器已启动,则在删除前先将其停止。任何由已删除的定时器生成的待处理信号的处理未指定。”
基本上这意味着我不知道回调是否会被调用,也没有方法来取消它或在清理资源之前强制挂起信号传递。请参见链接:http://man7.org/linux/man-pages/man2/timer_delete.2.html
class timer_wrapper
{
private:
std::function<void()> callback_;
timer_t timer_;
static void timer_callback(sigval_t val)
{
static_cast<timer_wrapper*>(val.sival_ptr)->callback_();
}
public:
timer_wrapper(std::function<void()> callback, uint32_t interval_sec)
: callback_(std::move(callback))
{
struct sigevent ev;
ev.sigev_notify = SIGEV_THREAD;
ev.sigev_signo = 0;
ev.sigev_value.sival_ptr = this;
ev.sigev_notify_function = &timer_wrapper::timer_callback;
ev.sigev_notify_attributes = 0;
timer_create(CLOCK_REALTIME, &ev, &timer_);
struct itimerspec spec = {{0, 0}, {interval_sec, 0}};
timer_settime(timer_, 0, &spec, nullptr);
}
~timer_wrapper()
{
timer_delete(timer_);
}
};
如果timer_wrapper超出范围,我希望回调不再被调用,然而有时候它仍会被调用,根据手册,这是期望的行为。如何解决这个问题?