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

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


相关文章
|
11月前
|
缓存 NoSQL 关系型数据库
MySQL 与 Redis 如何保证双写一致性?
我是小假 期待与你的下一次相遇 ~
1111 7
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
关系型数据库 应用服务中间件 nginx
Docker一键安装中间件(RocketMq、Nginx、MySql、Minio、Jenkins、Redis)
本系列脚本提供RocketMQ、Nginx、MySQL、MinIO、Jenkins和Redis的Docker一键安装与配置方案,适用于快速部署微服务基础环境。
|
11月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
1019 6
|
消息中间件 NoSQL Linux
Redis的基本介绍和安装方式(包括Linux和Windows版本),以及常用命令的演示
Redis(Remote Dictionary Server)是一个高性能的开源键值存储数据库。它支持字符串、列表、散列、集合等多种数据类型,具有持久化、发布/订阅等高级功能。由于其出色的性能和广泛的使用场景,Redis在应用程序中常作为高速缓存、消息队列等用途。
1168 16
|
缓存 NoSQL 中间件
Redis的线程模型
Redis采用单线程模型确保操作的原子性,每次只执行一个操作,避免并发冲突。它通过MULTI/EXEC事务机制、Lua脚本和复合指令(如MSET、GETSET等)保证多个操作要么全成功,要么全失败,确保数据一致性。Redis事务在EXEC前失败则不执行任何操作,EXEC后失败不影响其他操作。Pipeline虽高效但不具备原子性,适合非热点时段的数据调整。Redis 7引入Function功能,支持函数复用,简化复杂业务逻辑。总结来说,Redis的单线程模型简单高效,适用于高并发场景,但仍需合理选择指令执行方式以发挥其性能优势。
457 6
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
1. 先更新Mysql,再更新Redis,如果更新Redis失败,可能仍然不⼀致 2. 先删除Redis缓存数据,再更新Mysql,再次查询的时候在将数据添加到缓存中 这种⽅案能解决1 ⽅案的问题,但是在⾼并发下性能较低,⽽且仍然会出现数据不⼀致的问题,⽐如线程1删除了 Redis缓存数据,正在更新Mysql,此时另外⼀个查询再查询,那么就会把Mysql中⽼数据⼜查到 Redis中 1. 使用MQ异步同步, 保证数据的最终一致性 我们项目中会根据业务情况 , 使用不同的方案来解决Redis和Mysql的一致性问题 : 1. 对于一些一致性要求不高的场景 , 不做处理例如 : 用户行为数据 ,
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
|
缓存 NoSQL Java
Redis+Caffeine构建高性能二级缓存
大家好,我是摘星。今天为大家带来的是Redis+Caffeine构建高性能二级缓存,废话不多说直接开始~
1860 0
|
11月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
995 25

推荐镜像

更多