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:
-
Is such a periodic task better suited for
std::thread
orstd::async
? -
If we use
std::async
how long is the cleanUp function running? Until the DataManager gets destroyed? -
Is it considered good design to spin off an
std::async
orstd::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;
};
Best Answer
The main difference between spawning a thread directly and using
std::async
is that the latter gives you afuture
--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 (thefuture
) 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.