#include <future>
template<class T>
class SafeQueue
{
public:
SafeQueue() = default;
~SafeQueue() = default;
bool empty()
{
std::lock_guard<std::mutex> autoLock(m_mutex);
return m_queue.empty();
}
bool unEmpty()
{
std::lock_guard<std::mutex> autoLock(m_mutex);
return !m_queue.empty();
}
bool size()
{
std::lock_guard<std::mutex> autoLock(m_mutex);
return m_queue.size();
}
void push(const T& item)
{
std::lock_guard<std::mutex> autoLock(m_mutex);
m_queue.push(item);
}
bool popAndReturnByRef(T& first)
{
std::lock_guard<std::mutex> autoLock(m_mutex);
if (m_queue.empty())
return false;
first = std::move(m_queue.front());
m_queue.pop();
return true;
}
private:
std::queue<T> m_queue;
std::mutex m_mutex;
};
class ThreadPool
{
public:
ThreadPool(size_t num) : m_maxCount(num) {};
~ThreadPool()
{
Shutdown();
}
static ThreadPool* Get()
{
static ThreadPool pool(16);
return &pool;
}
template<class F, class...Args>
auto AddTask(F&& f, Args&&... args) -> std::future<decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
{
using ReturnType = decltype(std::forward<F>(f)(std::forward<Args>(args)...));
std::function<ReturnType(void)> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
std::shared_ptr<std::packaged_task<ReturnType(void)>> task_ptr = std::make_shared<std::packaged_task<ReturnType(void)>>(func);
std::function<void()> warpper_func =
[task_ptr]()->void
{
(*task_ptr)();
};
m_tasks.push(warpper_func);
m_conditionVariable.notify_one();
return task_ptr->get_future();
}
void setSize(int size)
{
m_maxCount = size;
}
void Run()
{
while (!m_isDone)
{
std::unique_lock<std::mutex> lock(m_mutex);
std::function<void(void)> func = nullptr;
if (m_tasks.empty())
{
m_conditionVariable.wait(lock);
}
m_tasks.popAndReturnByRef(func);
if (func)
{
lock.unlock();
func();
}
}
}
void Init()
{
m_arrThread.resize(m_maxCount);
for (int i = 0; i < m_maxCount; ++i) {
m_arrThread[i] = std::thread(&ThreadPool::Run, this);
}
}
void ThreadPool::Shutdown()
{
m_isDone = true;
m_conditionVariable.notify_all();
// 线程池结束工作
for (size_t i = 0; i < m_arrThread.size(); i++)
{
if (m_arrThread[i].joinable())
{
m_arrThread[i].join();
}
}
}
private:
bool m_isDone = false;
size_t m_maxCount;
std::mutex m_mutex;
std::condition_variable m_conditionVariable;
std::vector<std::thread> m_arrThread;
SafeQueue<std::function<void(void)>> m_tasks;
};
void text1()
{
for (int i = 0; i < 1e2; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::thread::id temp = std::this_thread::get_id();
std::wostringstream oss;
oss << temp;
std::wstring str = std::wstring(L" text1 == threadId :") + std::wstring(oss.str()) + std::wstring(L": i = ") + std::to_wstring(i) + std::wstring(L"\n");
OutputDebugString(str.c_str());
}
}
int text2(int num)
{
for (int i = 0; i < num; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::thread::id temp = std::this_thread::get_id();
std::wostringstream oss;
oss << temp;
std::wstring str = std::wstring(L" text2 == threadId :") + std::wstring(oss.str()) + std::wstring(L": i = ") + std::to_wstring(i) + std::wstring(L"\n");
OutputDebugString(str.c_str());
/* std::cout << "threadId :" << std::this_thread::get_id() << ": i = " << i << std::endl;*/
}
return num;
}
void Example()
{
ThreadPool pool(5);
pool.Init();
for (int i = 0; i < 10; ++i)
{
pool.AddTask(&text1);
}
int arg1 = 1e2;
auto data1 = pool.AddTask(&text2, arg1);
int a = data1.get();
{
std::thread::id temp = std::this_thread::get_id();
std::wostringstream oss;
oss << temp;
std::wstring str = std::wstring(L"threadId :") + std::wstring(oss.str()) + std::wstring(L": pool.AddTask(&text2, 2) = ") + std::to_wstring(a);
OutputDebugString(str.c_str());
}
std::future<int> data2 = pool.AddTask(&text2, arg1);
int a2 = data2.get();
std::thread::id temp = std::this_thread::get_id();
std::wostringstream oss;
oss << temp;
std::wstring str = std::wstring(L"threadId :") + std::wstring(oss.str()) + std::wstring(L": pool.AddTask(&text2, 2) = ") + std::to_wstring(a2);
OutputDebugString(str.c_str());
}
线程池 任务队列,线程队列。
于 2024-03-18 09:08:47 首次发布