1

I am writing a class which periodically has to check, if the data it manages is too old, if so it should delete it.

I am new to the C++11 multithreading library and I have the following questions:

  1. Is such a periodic task better suited for std::thread or std::async?

  2. If we use std::async how long is the cleanUp function running? Until the DataManager gets destroyed?

  3. Is it considered good design to spin off an std::async or std::thread in the constructor?

class DataManager {

public:

DataManager() {
    handle = std::async(
                std::launch::async,
                &DataManager:cleanUp, this);
}

...

void DataManager::cleanUp() {

    while (true) {

        std::this_thread::sleep_for(
                        std::chrono::seconds(DATA_COLLECTOR_PERIOD));

        for (auto& d: dataCollection) {
            if (d.isTooOld()) {
               dataCollection.remove(d);
            }
        }
    }
}

private:
  std::future<void> handle;
  std::vector<Foo> dataCollection;

};
9
  • 2
    Why don't you try both, and see which you like better? Commented Oct 17, 2016 at 14:59
  • @ Robert Harvey Matter of fact I did implement both versions, and I / Scott Meyers, prefers the std::async. But I am curious whether there in this specific situation I might miss some subtlety.
    – user695652
    Commented Oct 17, 2016 at 15:03
  • Good. That eliminates questions 1 and 3, leaving only question 2. The answer to question 2 is forever. (your loop says while (true) and contains no other exit condition) Commented Oct 17, 2016 at 15:05
  • For ever as in until the destructor of DataManager gets called?
    – user695652
    Commented Oct 17, 2016 at 15:07
  • 1
    It wasn't me, but I suspect that it's because questions like "better" and "best" aren't really answerable without knowing more about the specific problem you're trying to solve. Commented Oct 17, 2016 at 15:14

1 Answer 1

4

The main difference between spawning a thread directly and using std::async is that the latter gives you a future--a relatively clean wrapper for retrieving the result of a computation done in the thread.

In short, the intent1 here is to schedule a computation as soon as we can specify what we'll (eventually) need, and give the system maximum flexibility about carrying out that computation in the way that's most convenient, with the hope that it'll improve throughput.

That doesn't seem to fit this situation well at all. You're not spawning the thread to produce a result that you don't need yet. Rather, the thread is intended to run as an "agent" that does its own thing, with no real "end game" in sight. As such, most of what std::async provides (the future) compare to working directly with a thread is of no real use for the job at hand. As such, you might as well use the thread directly.

I don't see anything inherently wrong with creating a thread in a ctor.


1. The intent isn't reflected perfectly in the standard, but there's ongoing work to improve that.

2
  • Thanks for your answer. If I spin off an std::thread in a ctor, what's its lifetime?
    – user695652
    Commented Oct 17, 2016 at 17:20
  • That depends. If the thread object is defined in the class, it'll be destroyed when the object of that class is destroyed. If you allocate it dynamically, it'll be destroyed when you delete it. But usually, you'd want to create an object whose lifetime will match that of the behavior you want, so creating/destroying that object starts/stops the thread (and if that means creating it when main starts, and destroying it when main exits, that's perfectly fine). Commented Oct 17, 2016 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.