0

I am creating a worker process which waits for IDs on a pipe and against each ID tries to fetch some data. This fetch could take a while so I also create an async task to handle the time out logic.

The problem is if I send it multiple IDs through the pipe, it will work fine for the first 2 IDs but then randomly block until the timeout has expired after which it will take the next IDs.

My code is attached below, what I'm doing is that for each ID I create 2 async tasks (which I'm guessing run on their own threads) one task for the query (get_data) and the other for the time out. I'm not an expert but my understanding is that threads will be created for each message's async tasks while the main thread continues to read messages from the pipe.

Would appreciate if someone could guide me to figuring out why it blocks.

while (true)
{
    char message[100];
    read(comm_pipe[0], message, 100);

    long id = std::stol(message);
    bool done = false;
    std::mutex m;

    auto work = [&] {
        auto data = get_data(id);
        std::lock_guard<std::mutex> work_lock(m);
        if (!done)
        {
            done = true;
            save(id, data);
        }
    };

    auto async_timeout = [&] {
        std::this_thread::sleep_for(std::chrono::milliseconds(10000));

        std::lock_guard<std::mutex> timeout_lock(m);
        if (!done)
        {
            done = true;
            save(id, "time out");
        }
    };

    std::future<void> task = std::async(std::launch::async, work);
    std::future<void> timeout_task = std::async(std::launch::async, async_timeout);
}
user3690467
  • 3,049
  • 6
  • 27
  • 54
  • 1
    If you see e.g. [this `std::future` destructor reference](https://en.cppreference.com/w/cpp/thread/future/%7Efuture) you will see that there is a case it will block. And the destructor will be called for all objects inside the loop as it iterates the their lifetime ends. – Some programmer dude Aug 14 '18 at 18:23
  • So would pushing all the `futures` inside some global vector solve the problem? – user3690467 Aug 14 '18 at 18:24
  • you probably want [std::future::wait_for](https://en.cppreference.com/w/cpp/thread/future/wait_for). – Jarod42 Aug 14 '18 at 18:25
  • 1
    If you don't care about the results of the "threads" then you should probably use proper [threads](https://en.cppreference.com/w/cpp/thread/thread) which you [detach](http://en.cppreference.com/w/cpp/thread/thread/detach). Although then you have to capture by *value* instead of by reference. You might also want to consider thread pools? – Some programmer dude Aug 14 '18 at 18:26
  • This is what I ended up doing thank you!. Your first comment is likely the answer to my question so if you can post that as an answer I can choose it. – user3690467 Aug 14 '18 at 22:31

0 Answers0