mysql,redis客户端连接池和线程池的Windows C/C++编程实现(★firecat推荐★)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
简介: mysql,redis客户端连接池和线程池的Windows C/C++编程实现(★firecat推荐★)

一、环境准备:

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推荐★)


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL 关系型数据库 MySQL
2024Mysql And Redis基础与进阶操作系列(4-2)作者——LJS[含MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法]
24MySQL非空、唯一性、PRIMARY KEY、自增列/自增约束举例说明等详解步骤及常见报错问题对应的解决方法(4-2) 学不会你来砍我!!!
|
27天前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
58 14
|
2月前
|
API 开发工具 C#
神策SDK不支持Windows客户端全埋点,怎么实现用户统计分析?
本文将介绍,ClkLog针对神策不支持全埋点的客户端实现用户访问基础统计分析 1。
神策SDK不支持Windows客户端全埋点,怎么实现用户统计分析?
|
1月前
|
NoSQL 安全 关系型数据库
2024Mysql And Redis基础与进阶操作系列(6)作者——LJS[含MySQL 多表之一对一/多;多对多;多表联合查询等详解步骤及常见报错问题所对应的解决方法]
MySQL 多表之一对一/多;多对多;多表联合之交叉连接;内连接;左、右、外、满、连接;子查询及关键字;自连接查询等详解步骤及常见报错问题所对应的解决方法
|
1月前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
94 9
|
1月前
|
SQL NoSQL 关系型数据库
|
2月前
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
201 7
|
1月前
|
存储 SQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(1)作者——LJS[含MySQL的下载、安装、配置详解步骤及报错对应解决方法]
Mysql And Redis基础与进阶操作系列(1)之[MySQL的下载、安装、配置详解步骤及报错对应解决方法]
|
1月前
|
SQL 关系型数据库 MySQL