1

I want to run boost::asio::io_service.run() in a background thread. So when I need it post() func into.

This is main func:

int main(int /*argc*/, char** /*argv*/)
{
    std::string message = "hello";

    logg = new logger_client(filename,ip,13666);
    logg->start();

    while (true)
        logg->add_string(message);

    return 0;
}

And some relevant funcs from logger_client:

std::auto_ptr<boost::asio::io_service::work> work;

logger_client::logger_client(std::string& filename,std::string& ip, uint16_t port) : work(new boost::asio::io_service::work(io_service))
{
}

void logger_client::start()
{
    ios_thread = new boost::thread(boost::bind(&io_service.run,&io_service));
}

void print_nothing()
{
    printf("%s\n","lie");
}

void logger_client::add_string(std::string& message)
{
    io_service.post(boost::bind(print_nothing));
    //io_service.post(strand->wrap(boost::bind(&logger_client::add_string_imp,this,message)));
    //io_service.run();
}

When i run this, my program eats 2Gb less than a minute. If i remove endless work and change to this:

void logger_client::add_string(std::string& message)
{
    io_service.post(boost::bind(print_nothing));
    //io_service.post(strand->wrap(boost::bind(&logger_client::add_string_imp,this,message)));
    io_service.run();
}

Program works just fine. But I don't want to invoke async operations on this (main) thread. What am i doing wrong?

UPDATE

I added sleep(1sec) in while(true) loop and memory is no longer growing. But this is not a solution. Because if I call run() after post() (i.e. use main thread for processing handles) and even add five more threads with while(true) loops memory is not growing. So why main thread is so much better than newly created? I also tried thread pool for io_service::run - did not help.

alebaster
  • 23
  • 5
  • What makes you think your memory leak (or unbounded memory use that is not a leak) is in Boost code? Debugging code like your logger client is your job not StackOverflow. – Warren P Jun 22 '16 at 11:24
  • couse i comment string with post() and memory dont grow – alebaster Jun 22 '16 at 11:26
  • So you have Boost in the middle, and when the logger client receives strings, memory grows. So the logger client uses the memory. Clear. – Warren P Jun 22 '16 at 11:27
  • In this implementation string goes nowhere. And again: memory dont grow without post(), than dont use string. – alebaster Jun 22 '16 at 11:32
  • i think io_service really enqueuing handlers, but i see output (after adding io_service::work). – alebaster Jun 22 '16 at 13:44
  • 1
    The memory growth is because the loop `while (true)` enques handlers much faster than they can be handled. The memory growth is not a leak, it's just the memory used by handlers that are waiting to execute. There is no way it will ever catch up. – Chad Jun 22 '16 at 14:17
  • but if i explicit call run() from main thread he can handle it. And before i try to move io_service to separate thread asio successfully handle 6 outer threads with loop while(true). – alebaster Jun 22 '16 at 15:35
  • I also believe you are enqueueing much too fast. If you use sleep() you get printouts, correct? You could try boost::thread::yield(), but I still think it will be too intensive. You are not supposed to spam post's like that, the system has no chance to process them at that speed :) – Sven Nilsson Jun 23 '16 at 08:21
  • I think you are right, sleep for one microsec also work. Now I think how to catch this in case of emergency. Obviously it's kind of bad_alloc, but I cant catch(...) it. Also I know that there is no way to to determine current post() queue size to prevent it from growing. – alebaster Jun 23 '16 at 09:22

1 Answers1

2

io_service.run will exit unless there are pending operations.

Therefore, your ios_thread will exit immediately.

The solution is to use io_service::work.

In addition, endless loop spam like this

 while (true)
        logg->add_string(message);

is not a good idea, maybe add some sleep(), to slow it down a bit and keep it under control.

Sven Nilsson
  • 1,861
  • 10
  • 11