87 lines
1.8 KiB
C++
Executable File
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();
|
|
}
|
|
} |