boost deadline_timer issue - c++

Here follows the implementation of a test class wrapping a thread with a timer.
The strange thing is that if the deadline is set to 500 milliseconds it works but if I set it to 1000 milliseconds it does not. What am I doing wrong?
#include "TestTimer.hpp"
#include "../SysMLmodel/Package1/Package1.hpp"
TestTimer::TestTimer(){
thread = boost::thread(boost::bind(&TestTimer::classifierBehavior,this));
timer = new boost::asio::deadline_timer(service,boost::posix_time::milliseconds(1000));
timer->async_wait(boost::bind(&TestTimer::timerBehavior, this));
};
TestTimer::~TestTimer(){
}
void TestTimer::classifierBehavior(){
service.run();
};
void TestTimer::timerBehavior(){
std::cout<<"timerBehavior\r";
timer->expires_at(timer->expires_at() + boost::posix_time::milliseconds(1000));
timer->async_wait(boost::bind(&TestTimer::timerBehavior,this));
}
UPDATE 1
I have noticed that the program stucks (or at least the standard output in the console for many seconds, about 30) then a lot of "timerBehavior" strings are printed out together as if they have been queued somewhere.

You program might have several problems. From what you have shown, it's hard to say, if the program stops before the timer had a chance to trigger. And, you do not flush your output, use std::endl, if you want to flush the output after a newline. Third, if your thread is going to run the io_service.run() function, it might be that the thread finds an empty io queue and run() will return immediately. To prevent that, there is a work class, that will prevent this. Here is my example, from you code, that might work as expected:
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <iostream>
class TestTimer
{
public:
TestTimer()
: service()
, work( service )
, thread( boost::bind( &TestTimer::classifierBehavior,this ) )
, timer( service,boost::posix_time::milliseconds( 1000 ) )
{
timer.async_wait( boost::bind( &TestTimer::timerBehavior, this ) );
}
~TestTimer()
{
thread.join();
}
private:
void classifierBehavior()
{
service.run();
}
void timerBehavior() {
std::cout << "timerBehavior" << std::endl;
timer.expires_at( timer.expires_at() + boost::posix_time::milliseconds( 1000 ) );
timer.async_wait( boost::bind( &TestTimer::timerBehavior,this ) );
}
boost::asio::io_service service;
boost::asio::io_service::work work;
boost::thread thread;
boost::asio::deadline_timer timer;
};
int main()
{
TestTimer test;
}

Related

Incorrect Interval Timer for a CallBack function in C++

I find on the web this class to implement a callback function that asynchronously do some work while I'm on the Main thread. This is the class:
#include "callbacktimer.h"
CallBackTimer::CallBackTimer()
:_execute(false)
{}
CallBackTimer::~CallBackTimer() {
if( _execute.load(std::memory_order_acquire) ) {
stop();
};
}
void CallBackTimer::stop()
{
_execute.store(false, std::memory_order_release);
if( _thd.joinable() )
_thd.join();
}
void CallBackTimer::start(int interval, std::function<void(void)> func)
{
if( _execute.load(std::memory_order_acquire) ) {
stop();
};
_execute.store(true, std::memory_order_release);
_thd = std::thread([this, interval, func]()
{
while (_execute.load(std::memory_order_acquire)) {
func();
std::this_thread::sleep_for(
std::chrono::milliseconds(interval)
);
}
});
}
bool CallBackTimer::is_running() const noexcept {
return ( _execute.load(std::memory_order_acquire) &&
_thd.joinable() );
}
The problem here is that if I put a job to be done every millisecond I don't know why but it is repeated every 64 milliseconds and not every 1 millisecond, this snippet get an idea:
#include "callbacktimer.h"
int main()
{
CallBackTimer cBT;
int i = 0;
cBT.start(1, [&]()-> void {
i++;
});
while(true)
{
std::cout << i << std::endl;
Sleep(1000);
}
return 0;
}
Here I should see on the Standard Output: 1000, 2000, 3000, and so on. But it doesn't...
It's quite hard to do something on a PC in a 1ms interval. Thread scheduling happens at 1/64s, which is ~16ms.
When you try to sleep for 1 ms, it will likely sleep for 1/64s instead, given that no other thread is scheduled to run. As your main thread sleeps for one second, your callback timer may run up to 64 times during that interval.
See also How often per second does Windows do a thread switch?
You can try multimedia timers which may go down to 1 millisecond.
I'm trying to implement a chronometer in qt which should show also the microsecondo
Well, you can show microseconds, I guess. But your function won't run every microsecond.

What is the equivalent of Qtimer in C++ using std or boost libraries?

I have to perform some task every 5 seconds till the program exits. I don't want to use a thread here.
In QT I could do like this
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
but how do I do this in c++ using std or boost libraries?
Thank you
I have to assume that, by "I don't want to use a thread", you mean you don't want to create threads in your own code every time you need a timer. That's because doing it without threads is actually quite hard.
Assuming C++11, you can actually do this with just the core language (no Boost or any other stuff needed) and using a separate class handling the threading so that all you need in your own code is something like (for example, harassing your ex partner with spam emails, a rather dubious use case):
Periodic spamEx(std::chrono::seconds(60), SendEmaiToEx);
The following complete program, compiled with g++ -std=c++11 -o periodic periodic.cpp -lpthread will run a periodic callback function every second for five seconds(a):
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
// Not needed if you take couts out of Periodic class.
#include <iostream>
class Periodic {
public:
explicit Periodic(
const std::chrono::milliseconds &period,
const std::function<void ()> &func
)
: m_period(period)
, m_func(func)
, m_inFlight(true)
{
std::cout << "Constructing periodic" << std::endl;
m_thread = std::thread([this] {
while (m_inFlight) {
std::this_thread::sleep_for(m_period);
if (m _inFlight) {
m_func();
}
}
});
}
~Periodic() {
std::cout << "Destructed periodic" << std::endl;
m_inFlight = false;
m_thread.join();
std::cout << "Destructed periodic" << std::endl;
}
private:
std::chrono::milliseconds m_period;
std::function<void ()> m_func;
std::atomic<bool> m_inFlight;
std::thread m_thread;
};
// This is a test driver, the "meat" is above this.
#include <iostream>
void callback() {
static int counter = 0;
std::cout << "Callback " << ++counter << std::endl;
}
int main() {
std::cout << "Starting main" << std::endl;
Periodic p(std::chrono::seconds(1), callback);
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "Ending main" << std::endl;
}
When you create an instance of Periodic, it saves the relevant information and starts a thread to do the work. The thread (a lambda) is simply a loop which first delays for the period then calls your function. It continues to do this until the destructor indicates it should stop.
The output is, as expected:
Starting main
Constructing periodic
Callback 1
Callback 2
Callback 3
Callback 4
Ending main
Destructed periodic
(a) Note that the time given above is actually the time from the end of one callback to start of the next, not the time from start to start (what I would call true cycle time). Provided your callback is sufficiently quick compared to the period, the difference will hopefully be unnoticable.
In addition, the thread does this delay no matter what, so the destructor may be delayed for up to a full period before returning.
If you do require a start-to-start period and fast clean-up, you can use the following thread instead. It does true start-to-start timing by working out the duration of the callback and only delaying by the rest of the period (or not delaying at all if the callback used the entire period).
It also uses a smaller sleep so that clean-up is fast. The thread function would be:
m_thread = std::thread([this] {
// Ensure we wait the initial period, then start loop.
auto lastCallback = std::chrono::steady_clock::now();
while (m_inFlight) {
// Small delay, then get current time.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto timeNow = std::chrono::steady_clock::now();
// Only callback if still active and current period has expired.
if (m_inFlight && timeNow - lastCallback >= m_period) {
// Start new period and call callback.
lastCallback = timeNow;
m_func();
}
}
});
Be aware that, if your callback takes longer than the period, you will basically be calling it almost continuously (there'll be a 100ms gap at least).
You realize that QTimer does use a thread - or polls the timer in the main event loop. You can do the same. The conceptual problem you're likely having is that you don't have a UI and therefore, probably didn't create an event loop.
Here's the simplest way to leverage Boost Asio to have an event loop:
Live On Coliru
#include <boost/asio.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <functional>
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
using boost::system::error_code;
namespace ba = boost::asio;
int main() {
ba::io_service svc; // prefer io_context in recent boost versions
ba::high_resolution_timer timer{svc};
std::function<void()> resume;
resume = [&] {
timer.expires_from_now(50ms); // just for demo, don't wait 5s but 50ms
timer.async_wait([=,&timer](error_code ec) {
std::cout << "Timer: " << ec.message() << "\n";
if (!ec)
resume();
});
};
resume();
svc.run_for(200ms); // probably getting 3 or 4 successful callbacks
timer.cancel();
svc.run(); // graceful shutdown
}
Prints:
Timer: Success
Timer: Success
Timer: Success
Timer: Success
Timer: Operation canceled
That may not make too much sense depending on the rest of your application. In such cases, you can do the same but use a separate thread (yes) to run that event loop.

Timeout in C++ using Boost datetime

How to implement a timeout while loop in C++ using boost::datetime?
something like:
#define TIMEOUT 12
while(some_boost_datetime_expression(TIMEOUT))
{
do_something(); // do it until timeout expires
}
// timeout expired
Use Boost::deadline_timer for timeouts. Constant check of value in loop is overkill for CPU.
You'll first want to mark the time you start, then calculate the difference between the current time and the time you started. No built-in boost datetime expression will work exactly like you describe. In boost datetime terminology: http://www.boost.org/doc/libs/1_51_0/doc/html/date_time.html the duration of your timeout is a "time duration", and the point you start is a "time point".
Suppose you want to be accurate to within a second, and have a 4 minute 2 second interval.
using namespace boost::posix_time;
ptime start = second_clock::local_time();
gives you a time point to start your timing
ptime end = start + minutes(4)+seconds(2);
gives you a point in time 4 minutes and 2 seconds from now.
And then
( second_clock::local_time() < end )
is true if and only if the current time is before the end time.
(Disclaimer: this is not based off actually writing any boost datetime code before, but just reading the docs and example code over at the boost website.)
You can just check the time difference:
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
while((boost::posix_time::microsec_clock::local_time() - now) < boost::posix_time::milliseconds(TIMEOUT ) )
{
// do something
}
But instead of doing something like that you might rethink your design.
This can easily be done with boost.Asio. Start a deadline_timer as one async process. It cancels the event loop when it expires. Keep posting your work to the same event loop till it is running. A working solution:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class timed_job
{
public:
timed_job( int timeout ) :
timer_( io_service_, boost::posix_time::seconds( timeout ) ) // Deadline timer
{
}
void start()
{
// Start timer
timer_.async_wait
(
boost::bind
(
&timed_job::stop, this
)
);
// Post your work
io_service_.post
(
boost::bind
(
&timed_job::do_work, this
)
);
io_service_.run();
std::cout << "stopped." << std::endl;
}
private:
void stop()
{
std::cout << "call stop..." << std::endl;
io_service_.stop();
}
void do_work ()
{
std::cout << "running..." << std::endl;
// Keep posting the work.
io_service_.post
(
boost::bind
(
&timed_job::do_work, this
)
);
}
private:
boost::asio::io_service io_service_;
boost::asio::deadline_timer timer_;
};
int main()
{
timed_job job( 5 );
job.start();
return 0;
}

BOOST ASIO - How to write console server

I have to write asynchronous TCP Sever.
TCP Server have to be managed by console
(for eg: remove client, show list of all connected client, etcc..)
The problem is: How can I attach (or write) console, which can calls above functionalities.
This console have to be a client? Should I run this console client as a sepearate thread?
I have read a lot of tutorials and I couldn`t find a solution to my problem.
ServerTCP code
class ServerTCP
{
public:
ServerTCP(boost::asio::io_service& A_ioService, unsigned short A_uPortNumber = 13)
: m_tcpAcceptor(A_ioService, tcp::endpoint(tcp::v4(), A_uPortNumber)), m_ioService (A_ioService)
{
start();
}
private:
void start()
{
ClientSessionPtr spClient(new ClientSession(m_tcpAcceptor.io_service(), m_connectedClients));
m_tcpAcceptor.async_accept(spClient->getSocket(),
boost::bind(&ServerTCP::handleAccept, this, spClient,
boost::asio::placeholders::error));
}
void handleAccept(ClientSessionPtr A_spNewClient, const boost::system::error_code& A_nError)
{
if ( !A_nError )
{
A_spNewClient->start();
start();
}
}
boost::asio::io_service& m_ioService;
tcp::acceptor m_tcpAcceptor;
Clients m_connectedClients;
};
Main function:
try
{
boost::asio::io_service ioService;
ServerTCP server(ioService);
ioService.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
Hello Sam. Thanks for reply. Could you be so kind and show me a some piece of code or some links to examples involve with this problem ?
Propably, I don`t understand correctly "... single threaded server ..."
In Fact in "console" where I want to manage server operations, I need smt like below:
main()
cout << "Options: q - close server, s - show clients";
while(1)
{
char key = _getch();
switch( key )
{
case 'q':
closeServer();
break
case 's':
showClients();
break
}
}
The problem is: How can I attach (or
write) console, which can calls above
functionalities. This console have to
be a client? Should I run this console
client as a sepearate thread?
You don't need a separate thread, use a posix::stream_descriptor and assign STDIN_FILENO to it. Use async_read and handle the requests in the read handlers.
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace boost::asio;
class Input : public boost::enable_shared_from_this<Input>
{
public:
typedef boost::shared_ptr<Input> Ptr;
public:
static void create(
io_service& io_service
)
{
Ptr input(
new Input( io_service )
);
input->read();
}
private:
explicit Input(
io_service& io_service
) :
_input( io_service )
{
_input.assign( STDIN_FILENO );
}
void read()
{
async_read(
_input,
boost::asio::buffer( &_command, sizeof(_command) ),
boost::bind(
&Input::read_handler,
shared_from_this(),
placeholders::error,
placeholders::bytes_transferred
)
);
}
void read_handler(
const boost::system::error_code& error,
size_t bytes_transferred
)
{
if ( error ) {
std::cerr << "read error: " << boost::system::system_error(error).what() << std::endl;
return;
}
if ( _command != '\n' ) {
std::cout << "command: " << _command << std::endl;
}
this->read();
}
private:
posix::stream_descriptor _input;
char _command;
};
int
main()
{
io_service io_service;
Input::create( io_service );
io_service.run();
}
If I understand the OP correctly, he/she wants to run an async TCP server that is controlled via a console i.e console is used as user interface.
In that case you don't need a separate client application to query the server for connected clients, etc.:
You need to spawn a thread that somehow calls the io_service::run method. Currently you are calling this from main. Since your server will probably be scoped in main, you need do something like pass a ref to the server to the new thread. The io_service could e.g be a member of the server class (unless your application has other requirements in which case pass both the server and the io_service to the new thread).
add the corresponding methods such as showClients, closeServer, etc. to your server class
make sure that these calls which are triggered via the console are thread-safe
in your closeServer method you could for instance call io_service::stop which would result in the server ending.

Accurate continuous timer callback

Ive got an application where I want to display a frame every x milliseconds.
Previously I did it like this:
class SomeClass
{
boost::thread thread_;
boost::timer timer_;
public:
SomeClass() : thread_([=]{Display();})
{
}
void Display
{
double wait = 1.0/fps*1000.0;
while(isRunning_)
{
double elapsed = timer.elapsed()*1000.0;
if(elapsed < wait)
boost::this_thread::sleep(boost::posix_time::milliseconds(static_cast<unsigned int>(wait - elapsed)));
timer.restart();
// ... Get Frame. This can block while no frames are being rendered.
// ... Display Frame.
}
}
}
However I dont think solution has very good accuracy. I might be wrong?
I was hoping to used boost::asio::deadline_timer instead, but I'm unsure how to use it.
This is what ive tried, which doesn't seem to wait at all. It seems to just render the frames as fast as it can.
class SomeClass
{
boost::thread thread_;
boost::asio::io_service io_;
boost::asio::deadline_timer timer_;
public:
SomeClass() : timer_(io_, 1.0/fps*1000.0)
{
timer_.async_wait([=]{Display();});
thread_ = boost::thread([=]{io_.run();})
}
void Display
{
double wait = 1.0/fps*1000.0;
while(isRunning_)
{
timer_.expires_from_now(boost::posix_time::milliseconds(wait_)); // Could this overflow?
// ... Get Frame. This can block while no frames are being rendered.
// ... Display Frame.
timer_.async_wait([=]{Display();});
}
}
}
What am I doing wrong? And if I got this solution working would it be better than the first?
Here's a fairly trivial example using boost::asio::deadline_timer, hopefully it helps
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <iostream>
class Timer : public boost::enable_shared_from_this<Timer>
{
public:
Timer(
boost::asio::io_service& io_service
) :
_io_service( io_service ),
_timer( io_service )
{
}
void start() {
_timer.expires_from_now(
boost::posix_time::seconds( 0 )
);
_timer.async_wait(
boost::bind(
&Timer::handler,
shared_from_this(),
boost::asio::placeholders::error
)
);
}
private:
void handler(
const boost::system::error_code& error
)
{
if ( error ) {
std::cerr << error.message() << std::endl;
return;
}
std::cout << "handler" << std::endl;
_timer.expires_from_now(
boost::posix_time::seconds( 1 )
);
_timer.async_wait(
boost::bind(
&Timer::handler,
shared_from_this(),
boost::asio::placeholders::error
)
);
}
private:
boost::asio::io_service& _io_service;
boost::asio::deadline_timer _timer;
};
int
main()
{
boost::asio::io_service io_service;
boost::shared_ptr<Timer> timer(
new Timer( io_service )
);
timer->start();
io_service.run();
}
Remember that the accuracy with which a frame is displayed is limited by the refresh rate of your display (typically 17 ms for a 60 Hz display, or 13 ms for a 75 Hz display). If you're not syncing to the display refresh then you have an indeterminate latency of 0 - 17 ms to add to whatever timing method you use, hence accuracy doesn't really need be much better than 10 ms (even 1 ms is probably overkill).