Domanda

Ho provato ad usare il boost deadline_timer in questa semplice applicazione di test, ma ha avuto alcuni problemi.L'obiettivo è che il timer per attivare ogni 45 millisecondi utilizzando il expires_at() funzione di membro del deadline_timer.(Ho bisogno di un tempo assoluto, quindi non sto considerando expires_from_now().Anche io sono preoccupata per la deriva al momento).Quando ho eseguito il programma, wait() non aspettare 45 ms!Di sicurezza, non vengono segnalati errori.Sto utilizzando la libreria in modo non corretto in qualche modo?

Programma di esempio:

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace std;

int main()
{
        boost::asio::io_service Service;
        boost::shared_ptr<boost::thread> Thread;
        boost::asio::io_service::work RunForever(Service);
        Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
        boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));

        while(1)
        {
                boost::posix_time::time_duration Duration;
                Duration = boost::posix_time::microseconds(45000);
                boost::posix_time::ptime Start = boost::posix_time::microsec_clock::local_time();
                boost::posix_time::ptime Deadline = Start + Duration;
                boost::system::error_code Error;
                size_t Result = Timer->expires_at(Deadline, Error);
                cout << Result << ' ' << Error << ' ';
                Timer->wait(Error);
                cout << Error << ' ';
                boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
                (cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
        }
        return 0;
}
È stato utile?

Soluzione

Il missaggio ora locale con il tempo di sistema.Il tempo asio è a confrontare la vostra ora locale è più probabile che un certo numero di ore dopo il tempo che si desidera che il termine fissato per attendere che restituisce immediatamente (a seconda di dove si vive;questo stesso codice può aspettare per diverse ore).Per evitare questa confusione, in assoluto i tempi dovrebbero essere derivato da asio::time_traits.

#include <boost/asio.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <iostream> 
using namespace std;

typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;  
int main() {         
    boost::asio::io_service Service;         
    boost::shared_ptr<boost::thread> Thread;         
    boost::asio::io_service::work RunForever(Service);         
    Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
    boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));          
    while(1)         
    {                 
        boost::posix_time::time_duration Duration;
        Duration = boost::posix_time::microseconds(45000);
        boost::posix_time::ptime Start = time_traits_t::now();
        boost::posix_time::ptime Deadline = Start + Duration;
        boost::system::error_code Error;
        size_t Result = Timer->expires_at(Deadline, Error);
        cout << Result << ' ' << Error << ' ';
        Timer->wait(Error);
        cout << Error << ' ';
        boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
        (cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
     }         
    return 0; 
}

Che dovrebbe funzionare per voi, in questo caso.

Altri suggerimenti

Stai mescolando metodi asincroni io_service::run con metodi sincroni deadline_timer::wait. Questo non funzionerà. O usare deadline_timer::async_wait insieme a io_service::run, o saltare il io_service::run E solo usare deadline_timer::wait. Inoltre non hai bisogno di un thread per invocare io_service:run Se segui il percorso asincrono, un thread andrà bene. Entrambi i concetti sono spiegati in dettaglio nel Competenze di base sezione del Tutorial ASIO.

void print(const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, world!\n";
}

int main()
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
  t.async_wait(print);
  io.run();

  return 0;
}

Nota che dovrai dare un po 'di lavoro per il tuo io_service al servizio prima di invocare run(). In questo esempio, async_wait è quel lavoro.

Potenzialmente non correlato: 45ms è un delta piuttosto piccolo. Nella mia esperienza il tempo più piccolo per qualsiasi gestore di subire attraverso la coda del reattore di Epoll ASIO è di circa 30 ms, questo può essere considerevolmente più lungo a carichi più elevati. Anche se tutto dipende in gran parte dalla tua applicazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top