zynq_7010/zynq_7010_code/threadex.h

87 lines
1.8 KiB
C++
Executable File

#pragma once
#include <thread>
#include <future>
#include <functional>
#ifdef WIN32
#include <Windows.h>
#endif // WIN32
class ThreadEx {
public:
template<class F, class... Args>
ThreadEx(F&& f, Args&&... args);
~ThreadEx();
bool is_runing(int time = 0);
void cannel(int time = 0);
private:
std::future<void> fu_run;
#ifdef WIN32
std::thread::id fu_run_id;
void* threadHandle;
#else
pthread_t fu_run_id;
#endif // WIN32
};
// the constructor just launches some amount of workers
template<class F, class... Args>
inline ThreadEx::ThreadEx(F&& f, Args&&... args)
{
auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
fu_run = std::async(std::launch::async, [this, task](){
#ifdef WIN32
std::thread runThread(task, this);
threadHandle = runThread.native_handle();
if (runThread.joinable())
{
runThread.join();
}
//fu_run_id = std::this_thread::get_id();
#else
fu_run_id = pthread_self();
task();
#endif // WIN32
});
}
inline ThreadEx::~ThreadEx()
{
cannel();
}
inline bool ThreadEx::is_runing(int time)
{
return fu_run.valid() && (fu_run.wait_for(std::chrono::milliseconds(time == 0 ? 1000 : time)) != std::future_status::ready);
}
inline void ThreadEx::cannel(int time)
{
if (is_runing(time))
{
#ifdef WIN32
DWORD result = ::TerminateThread(threadHandle, 1);
if (result != 0)
{
std::cout << "Successfully terminated thread\n";
}
else
{
std::cout << "Failed to terminate thread: failure resson " << ::GetLastError() << "\n";
}
#else
pthread_cancel(fu_run_id);
#endif // WIN32
fu_run.wait();
}
}