C标准:C17
我得到一个错误,而启动计时器指出:Invalid argument
。
当我检查计时器id的值时,它是零(0),但是我的timer_create()成功执行,因为它返回0。
有什么问题吗?
代码
表头
#pragma once
#include <ctime>
#include <csignal>
#include <cstdint>
#include <functional>
//#include <timerLib.h>
class Timer
{
public:
Timer(bool periodic = false) : periodic(periodic){}
~Timer();
bool create(void);//Create timer only
bool create(std::uint64_t timeout);//Create timer, set timeout and start timer
bool update(std::uint64_t timeout);//Stop timer, update set timeout and start timer
bool start(std::uint64_t timeout);//Set timeout and start timer
bool start(void);//Starts the timer with the timeout value (refer private timeout variables)
bool stop(void);//Stops the timer
bool destroy(void);//Destroys the timer. Can't be reused without calling create
using callback_timer_t = std::function<void(void)>;
void registerCallback(callback_timer_t callback);
private:
bool periodic;
std::uint64_t timeout;// in nano-seconds
timer_t timer_id;
sigset_t mask;
long long freq_nanosecs;
struct sigevent sev;
struct sigaction sa;
struct itimerspec its;
static void handler(int sig, siginfo_t *si, void *uc);
callback_timer_t callback;
};
字符串
来源
#include "timer.hpp"
#include <iostream>
#include <cstdio>
//The range of supported real-time signals is defined by the macros SIGRTMIN and SIGRTMAX.
//Programs should never refer to real-time signals using hard-coded numbers, but instead should always refer to
//real-time signals using the notation SIGRTMIN+n, and include suitable (run-time) checks that SIGRTMIN+n
//does not exceed SIGRTMAX
//the top priority RT signal is SIGRTMIN; the least (lowest) priority RT signal is SIGRTMAX.
//If different real-time signals are sent to a process, they are delivered starting with the lowest-numbered signal.
//(i.e., low-numbered signals have highest priority.)
#define SIG SIGRTMIN
Timer::~Timer()
{
this->destroy();
}
bool Timer::create(void)
{
int returnValue;
//Establish handler for timer signal.
this->sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&this->sa.sa_mask);
if (sigaction(SIG, &this->sa, nullptr) == -1)
{
//Log Error
perror("sigaction");
return false;
}
//Block timer signal temporarily.
printf("Blocking signal %d\n", SIG);
sigemptyset(&mask);
sigaddset(&mask, SIG);
if (sigprocmask(SIG_SETMASK, &this->mask, nullptr) == -1)
{
perror("sigprocmask");
return false;
}
//Create a timer
this->sev.sigev_notify = SIGEV_SIGNAL; //Upon timer expiration, generate the signal sigev_signo for the process.
this->sev.sigev_signo = SIG;
this->sev.sigev_value.sival_ptr = this;
returnValue = timer_create(CLOCK_REALTIME, &this->sev, &this->timer_id);
std::cout << "Timer Create Return Value : " << returnValue << std::endl;
if(returnValue == -1)
{
//Log Error
perror("timer_create");
return false;
}
//# -> Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero.
//j -> The length sub-specifier modifies the length of the data type : uintmax_t
std::printf("timer ID is %#jx\n", (uintmax_t) timer_id); //Only for testing
return true;
}
bool Timer::create(std::uint64_t timeout)
{
bool return_status = this->create();
if(return_status == false)
{
return false;
}
return this->start(timeout);
}
bool Timer::update(std::uint64_t timeout)
{
bool return_status = this->stop();
if(return_status == false)
{
return false;
}
return this->start(timeout);
}
bool Timer::start(std::uint64_t timeout)
{
this->its.it_value.tv_sec = 0;
this->its.it_value.tv_nsec = timeout;
if(periodic == true)
{
this->its.it_interval.tv_sec = 0;
this->its.it_interval.tv_nsec = timeout;
}
else
{
this->its.it_interval.tv_sec = 0;
this->its.it_interval.tv_nsec = 0;
}
return this->start();
}
bool Timer::start(void)
{
int return_status = timer_settime(this->timer_id, 0, &this->its, nullptr);
if(return_status == -1)
{
//TODO Log Error
perror("timer_settime");
return false;
}
//TODO Remove in final code
std::cout << "Timer Started\n";
return true;
}
bool Timer::stop(void)
{
struct itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
int return_status = timer_settime(this->timer_id, 0, &its, nullptr);
if(return_status == -1)
{
//TODO Log Error
perror("timer_settime");
return false;
}
//TODO Remove in final code
std::cout << "Timer Stopped\n";
return true;
}
bool Timer::destroy(void)
{
int return_status = timer_delete(this->timer_id);
if(return_status == -1)
{
return false;
}
else
{
return true;
}
}
void Timer::registerCallback(callback_timer_t callback)
{
this->callback = callback;
}
void Timer::handler(int sig, siginfo_t *si, void *uc)
{
Timer *timer = reinterpret_cast<Timer*>(si->si_value.sival_ptr);
timer->callback();
}
型
联系我们
#include "timer.hpp"
#include <iostream>
void timer_callback(void)
{
std::cout << "Timeout\n";
}
int main(int argc, char *argv[])
{
Timer t(true);
t.registerCallback(timer_callback);
if(t.create(1000000000ul) == false)
{
std::cout << "Timer Create Failed.\tExitting Application.\n";
return -1;
}
while (true)
{
/* code */
}
return 0;
}
型
输出
Blocking signal 34
Timer Create Return Value : 0
timer ID is 0
timer_settime: Invalid argument
Timer Create Failed. Exitting Application.
型
CMakeLists.txt
cmake_minimum_required(VERSION 3.6.2)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(timer_lib C CXX ASM)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -g")
SET(MY_TARGET ${PROJECT_NAME}.out)
add_executable(${MY_TARGET}
main.cpp
timer.cpp
)
型
1条答案
按热度按时间mtb9vblg1#
struct timespec
中tv_nsec
是999999999
,小于1000000000ul
。如果你想睡眠超过一秒,那么考虑使用tv_sec
。