I'm getting requests through a (thread-safe) queue. Each request than needs to be handled in a separate thread. There is a chance that the function (which is actually calling a Java-program via _popen
and polling its output) takes a very long time. From the main thread I need a mechanism to indicate that situation (basically, measuring thread-running-time).
In my example I'm trying to 'enrich' std::future
with some time information. The sample runs seamlessly, but I'm uncertain if this is the correct way. Also, even if it is the 'correct' way, I'm having trouble writing a copy-constructor and a assignment operator for CFutureTest
, which I would like to control myself.
Here is a very simple demo that mimics what I'm trying to achieve:
typedef std::future<int> FutureResultInt;
int ThreadFunc() {
std::random_device rd;
std::mt19937 mt(rd());
const int iRand = std::uniform_int_distribution<int>(2000, 6000)(mt);
std::cout << "ThreadFunc waiting for [" << iRand << "] ms ... " << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(iRand));
std::cout << "ThreadFunc [" << iRand << "] done" << std::endl;
return iRand;
}
class CFutureTest {
public:
CFutureTest() = delete;
CFutureTest(FutureResultInt&& fr)
: m_start(std::chrono::system_clock::now()), m_result() {
m_result = std::move(fr);
};
int GetAge() const {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now() - m_start)
.count();
}
// private:
FutureResultInt m_result;
std::chrono::time_point<std::chrono::system_clock> m_start;
};
int main() {
std::vector<CFutureTest> futures;
for (int i = 0; i < 5; i++)
futures.push_back(std::move(std::async(std::launch::async, ThreadFunc)));
while (futures.size() > 0) {
for (std::vector<CFutureTest>::iterator it = futures.begin();
it != futures.end(); ++it) {
CFutureTest& future = *it;
const std::future_status stat =
future.m_result.wait_for(std::chrono::milliseconds(1));
switch (stat) {
case std::future_status::timeout:
if (future.GetAge() > 4000) {
std::cout << "Thread has exceeded the time limit" << std::endl;
}
continue;
case std::future_status::deferred:
std::cout << "std::future_status::deferred" << std::endl;
continue;
}
const int iResult = future.m_result.get();
std::cout << "future returned [" << iResult << "] (removing!)"
<< std::endl;
futures.erase(it);
if (futures.size() < 1) break;
it = futures.begin();
}
}
return 0;
}