Scenario: I'm getting requests through a (thread-safe) queue. Each request then 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.
Here is a very simple demo that mimics what I'm trying to achieve (where ThreadFunc
stands in for my real processing code):
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <random>
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;
}