#pragma once #include #include #include #ifdef WIN32 #include #endif // WIN32 class ThreadEx { public: template ThreadEx(F&& f, Args&&... args); ~ThreadEx(); bool is_runing(int time = 0); void cannel(int time = 0); private: std::future 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 inline ThreadEx::ThreadEx(F&& f, Args&&... args) { auto task = std::bind(std::forward(f), std::forward(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(); } }