2

I am using Boost 1.55 in Linux with gcc 4.8.

I commonly use boost::asio combined with std::promise/std::future but, sometimes, my program is deadlocked. This is a simplified program which shows that behaviour.

// Compile with: g++ -std=c++11 main.cpp -lpthread -lboost_system
#include <memory>
#include <functional>
#include <thread>
#include <future>
#include <cassert>

#include <boost/asio.hpp>

int main(int argc, char *argv[]) {
    boost::asio::io_service ioService;
    std::unique_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(ioService));
    std::thread ioThread([&] () {
        ioService.run();
    });

    for (int i=0; i<1000; i++) {
        std::promise<bool> prom;
        std::future<bool> fut = prom.get_future();
        ioService.post([&prom] () {
            prom.set_value(true);
        });

        assert(fut.get());
    }

    work.reset();
    ioThread.join();
}

Am I correctly using the boost::asio::io_service? Debugging the program, the two threads are deadlocked calling the promise::set_value() and the future::get() methods. It seems that std::promise::set_value() uses the call_once() function that hangs when calling an internal Pthread function.

In Windows (using MSYS2), the program works OK. Also, if I substitute the Boost.Asio code with a std::thread based code (new thread per iteration), the example works OK.

Thanks in advance.

Angel
  • 21
  • 3
  • 2
    That `assert(fut.get());` looks questionable –  Jan 02 '15 at 17:59
  • @DieterLücking If I remove the `assert()` and leave the `fut.get();` alone, or simply `fut.wait();`, the call hangs the same way. – Angel Jan 02 '15 at 18:16
  • @Angel - Boost is not really thread safe. Its controversial for the Fan Boi's, but I performed the audit and filed the bug reports myself. I'd recommend you avoid from multithreaded programs when using Boost. – jww Jan 02 '15 at 18:28
  • 1
    Your usage of `io_service` is correct. On the other hand, the lifetime of the `std::promise` is problematic. See [this](http://stackoverflow.com/questions/10843304) question for details. – Tanner Sansbury Jan 02 '15 at 22:37
  • 1
    @jww: This just in: Software has bugs. For the future, you might want to consider not only how many bugs are in Boost, but also to compare that against the severity of bugs in you duplicating their work. – Puppy Jan 02 '15 at 22:48
  • 1
    @jww *All the Boost*? This seems rather too far-fetched, considering Boost is a set of about 130 loosely dependent libraries. – milleniumbug Jan 02 '15 at 23:02
  • @milleniumbug - I don't know how deep the rabbit hole goes with Boost. I was surprised at how many CompSci 101 mistakes there were, and I was alarmed at some of the results I got when investigating them. Because of the acceptance testing results, Boost was simply banned from the project. Also Boost seems to lack a Q&A process, so it was a governance issue too. – jww Jan 03 '15 at 00:10
  • @Puppy - that's kind of funny. Apparently, Boost has not considered how many bugs they've introduced by re-implementing the same features multiple times. (Hint: have a look at the multithreading code, and then search for things like `WaitForSingleObject`. How is it your hitting on functions like that in so many different places, rather than just one place?). – jww Jan 03 '15 at 00:13
  • @TannerSansbury Thanks! I didn't find that question because I was looking for one related with Boost.Asio. Obviously, my "std::thread base code" was not equivalent to the problematic one. BTW, if I use boost::promise / boost::future, the code works OK. Maybe, with the Boost implementation, the race-condition is less probable. – Angel Jan 03 '15 at 12:58

0 Answers0