boost deadline_timer nie wola wszystkich callbackow

0
#include <iostream>
#include <chrono>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <thread>     
#include <boost/bind.hpp>
class DeadlineTimerWrapper {   
    public:
        DeadlineTimerWrapper() : m_thread(std::make_shared<std::thread>(&DeadlineTimerWrapper::run, this)), m_stop(false){

        }
        ~DeadlineTimerWrapper() {          
           m_stop = true;
           m_thread->join();
        }
        void run() {
               std::unique_lock<std::mutex> lck(m_mutex);
            while(1) {
               m_cv.wait(lck, boost::bind(&DeadlineTimerWrapper::isSth, this));
               m_io.run();
               if(m_stop)
                   break;
               std::cout << "\n size: " << m_map.size() << "\n";
            }
        }
        void add(int a) {
            std::shared_ptr<boost::asio::deadline_timer> temp = std::make_shared<boost::asio::deadline_timer>(m_io);
            {
                std::unique_lock<std::mutex> lck(m_mutex); 
                m_map[a] = temp;                
                m_map[a]->expires_from_now(boost::posix_time::seconds(2));
                m_map[a]->async_wait(boost::bind(&DeadlineTimerWrapper::callback, this, _1, a));
                m_cv.notify_one();          
            }
        }
        void callback(const boost::system::error_code& err, int i) {
            std::cout << "\n-----------------CALLBACK------------------\n";
            std::cout << i << "m_map.size(): " << m_map.size() << boost::asio::time_traits< boost::posix_time::ptime >::now() << " " << m_map[i]->expires_at()<< "\n";
            m_map.erase(i);
        }
    private:

        bool isSth() {return !m_map.empty();}
        std::shared_ptr<std::thread> m_thread;
        boost::asio::io_service m_io;   
        std::map<int, std::shared_ptr<boost::asio::deadline_timer>> m_map;
        std::condition_variable m_cv;   
        std::mutex m_mutex;
        std::atomic<bool> m_stop;
};

int main(int argc, char* argv[]) {  
    DeadlineTimerWrapper t;
    int k = 0 ;
    int j = 10000 ;
    while(k < 20) {
       t.add(k++);
       std::this_thread::sleep_for(std::chrono::seconds(19));
    }
    while(1) ;
    return 0;
}
 

Dlaczego po wywołaniu pierwszego callbacka, m_io.run(); w ogóle się nie blokuje i nie woła callbacków, które sa dodawane do mapy ?

0

Dołączam output programu:

-----------------CALLBACK------------------
0m_map.size(): 12016-Dec-09 08:45:15.985781 2016-Dec-09 08:45:15.985340

size: 0

size: 1

size: 1

size: 1

size: 1

size: 1

1

Okazało się, że m_io.run może być wołane powtórnie tylko po tym jak ioservice wywoła reset
więc trzeba dodać:

m_io.run();
m_io.reset()

i działa, temat do usunięcia

1

i działa, temat do usunięcia

  1. albo do usunięcia (czego na tym forum raczej się nie robi) a wtedy twoja odpowiedź idzie na marne, bo kto ją przeczyta? albo
  2. twoja odpowiedź może się przydać komuś w przyszłości, a wtedy chyba jasne że temat usuwany nie będzie.
0

ok, to jeżeli kogoś by kiedys interesowało to tutaj cały kod:

 
#include <chrono>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <boost/bind.hpp>


template<class T>
class SelfCleaningSet {
    public:
        SelfCleaningSet(boost::posix_time::milliseconds t = boost::posix_time::milliseconds(1000)) :
                        m_ttl(t),
                        m_stop(false),
                        m_thread(std::make_shared<std::thread>(&SelfCleaningSet::monitor, this))
        {}

        ~SelfCleaningSet() {
            m_stop = true;
            if(m_thread->joinable())
                m_thread->join();
            }

        void store(T key) {
            std::shared_ptr<boost::asio::deadline_timer> temp = std::make_shared<boost::asio::deadline_timer>(m_io, m_ttl);
            {
                std::lock_guard<std::mutex> lck(m_mutex);
                m_storage[key] = temp;
            }
            temp->async_wait(boost::bind(&SelfCleaningSet::clear, this, _1, key));
        }

        bool exists(T key) {
            std::lock_guard<std::mutex> lck(m_mutex);
            return m_storage.find(key) != m_storage.end();
        }

    private:

        void monitor() {
            auto func = boost::bind(&SelfCleaningSet::pred, this);
            while(!m_stop) {
                m_io.run();
                m_io.reset();
            }
        }

        bool pred() { return m_stop ? false : !m_storage.empty(); }

        void clear(const boost::system::error_code& err, T key) {
            std::lock_guard<std::mutex> lck(m_mutex);
            if(!err)
                m_storage.erase(key);
        }

        boost::posix_time::milliseconds m_ttl;
        std::map<T, std::shared_ptr<boost::asio::deadline_timer>> m_storage;
        std::atomic<bool> m_stop;
        std::mutex m_mutex;
        boost::asio::io_service m_io;
        std::shared_ptr<std::thread> m_thread;
};

1 użytkowników online, w tym zalogowanych: 0, gości: 1