一、環境準備:
Windows,VS2015
Mysql使用官方c語言版本用戶端,mysql-connector-c-6.1.10-win32.zip,不使用c++庫,因為c++庫依賴boost庫
https://downloads.mysql.com/archives/c-c/ 庫函數和頭檔案使用方法參見 http://blog.csdn.net/libaineu2004/article/details/79607432 Redis使用開源的cpp_redis庫,是c++語言實作 https://github.com/Cylix/cpp_redis v4.3.1 https://github.com/Cylix/tacopie v3.2.0 https://cylix.github.io/cpp_redis/html/classcpp__redis_1_1client.html http://blog.csdn.net/libaineu2004/article/details/79582185 二、完整的工程源碼下載下傳位址: https://download.csdn.net/download/libaineu2004/10300060源碼涉及線程池和連接配接池的實作,C++11文法,關注一下線程安全退出的方法
ThreadPool.cpp
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include "ThreadPool.h"
///
CWorkerThread::CWorkerThread()//:m_thread(StartRoutine, this) //c++中類的成員對象初始化
{
m_thread_idx = 0;
m_task_cnt = 0;
m_task_list.clear();
}
CWorkerThread::~CWorkerThread()
{
}
void CWorkerThread::Start()
{
//t[i] = thread(std::mem_fn(&MyClass::thread_func), Object, args..);
//thread t(std::bind(&TestThread::run, this));
m_bExit = false;
thread t(StartRoutine, this);
t.detach();
}
void* CWorkerThread::StartRoutine(void* arg)
{
CWorkerThread* pThread = (CWorkerThread*)arg;
pThread->m_bRunning = true;
pThread->Execute();
pThread->m_bRunning = false;
return NULL;
}
void CWorkerThread::Stop(void)
{
m_mutex.lock();
m_bExit = true;
m_task_list.clear();
m_mutex.unlock();
}
void CWorkerThread::Execute()
{
while (true) {
// put wait in while cause there can be spurious wake up (due to signal/ENITR)
while (m_task_list.empty()) {
if (m_bExit)
{
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));//等同于Sleep(1);
continue;
}
m_mutex.lock();
CTask* pTask = m_task_list.front();
m_task_list.pop_front();
m_mutex.unlock();
pTask->run();
delete pTask;
pTask = NULL;
m_task_cnt++;
printf("thread%d have the execute %d task\n", m_thread_idx, m_task_cnt);
//printf("test thread id:%xH\n", std::this_thread::get_id());//這個傳回的id不是整數,不能直接列印輸出
}
}
void CWorkerThread::PushTask(CTask* pTask)
{
m_mutex.lock();
m_task_list.push_back(pTask);
m_mutex.unlock();
}
//
CThreadPool::CThreadPool()
{
m_worker_size = 0;
m_worker_list = NULL;
}
CThreadPool::~CThreadPool()
{
Destory();
}
int CThreadPool::Init(uint32_t worker_size)
{
m_worker_size = worker_size;
m_worker_list = new CWorkerThread[m_worker_size];
if (!m_worker_list) {
return 1;
}
for (uint32_t i = 0; i < m_worker_size; i++) {
m_worker_list[i].SetThreadIdx(i);
m_worker_list[i].Start();
}
return 0;
}
void CThreadPool::Destory()
{
if (m_worker_list)
{
for (int i = 0; i < m_worker_size; i++)
{
m_worker_list[i].Stop();
}
for (int i = 0; i < m_worker_size; i++)
{
while (m_worker_list[i].IsRunning())
{
Sleep(1);//等待線程安全退出
}
}
delete [] m_worker_list;
m_worker_list = NULL;
}
}
void CThreadPool::AddTask(CTask* pTask)
{
/*
* select a random thread to push task
* we can also select a thread that has less task to do
* but that will scan the whole thread list and use thread lock to get each task size
*/
uint32_t thread_idx = rand() % m_worker_size;
m_worker_list[thread_idx].PushTask(pTask);
}
ThreadPool.h
#ifndef THREADPOOL_H_
#define THREADPOOL_H_
#include <stdio.h>
#include <stdint.h>
#include <string>
#include <string.h>
#include "Task.h"
#include <list>
#include <thread>
#include <mutex>
using namespace std;
class CWorkerThread {
public:
CWorkerThread();
~CWorkerThread();
static void* StartRoutine(void* arg);
void Start(void);
void Stop(void);
void Execute(void);
void PushTask(CTask* pTask);
void SetThreadIdx(uint32_t idx) { m_thread_idx = idx; }
bool IsRunning(void) { return m_bRunning; }
private:
uint32_t m_thread_idx;
uint32_t m_task_cnt;
//thread m_thread;
mutex m_mutex;
list<CTask*> m_task_list;
bool m_bExit;
bool m_bRunning;
};
class CThreadPool {
public:
CThreadPool();
virtual ~CThreadPool();
int Init(uint32_t worker_size);
void AddTask(CTask* pTask);
void Destory();
private:
uint32_t m_worker_size;
CWorkerThread* m_worker_list;
};
#endif /* THREADPOOL_H_ */
三、歡迎通路姊妹篇
mysql,redis用戶端連接配接池和線程池的Linux C程式設計實作(★firecat推薦★)