基于C++写一个mysql连接池

数据库连接池c++ (msyql) mysql connector c++ 的使用 Mysql Connector/C++ 使用介绍 一、下载mysql connector c++ 和 boost库 wget   https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-1.1.8-linux-glibc2.5-x86-64bit.tar.gz 下载:根据自己的系统下载mysql con 阅读详情

思想:封装mysql基本操作API,以stl中的list容器包装连接对象,采用单例模式创建连接池类对象,采取RAII机制进行实现。其中,涉及到对连接队列的操作的,全部都加上互斥锁,保证原子操作。

具体的,Pool类成员变量包括:

主机名或IP地址m_url,如果NULL或"localhost",连接将被视为与本地主机的连接。
数据库名称m_dbName、
登录用户名m_dbUser、
用户密码m_dbPswd、
连接端口m_port,
当前连接数m_curconn、
空闲连接数m_freeconn以及一个封装了互斥量的locker类对象Lock,封装了信号量的sem类对象rest。

主要接口有:

初始化接口init,
获取空闲连接数接口getFreeconn,
释放一个连接接口releaseConn,
销毁连接池接口Destroy以及
单例模式获取唯一实例接口getInstance。

最后,RAIIPool类实现RAII机制,在构造函数中获取唯一实例,析构函数销毁连接池。

代码如下

#pragma once

class Pool{
public:
    ~Pool();
    int getFreeconn();
    bool init(string url, string dbName, string dbPswd, string User, int port);
    void Destroy();  //销毁连接池
    void releaseConn(MYSQL* conn);   //释放一个连接
    MYSQL* GetConn();     //获取一个空闲连接
    Pool* getInstance();  //单例连接
    
private:
    Pool();
    list<MYSQL*> pool_;
    string m_dbName;
    string m_dbPswd;
    string m_dbUser;
    string m_port;
    string m_url;

    constexpr static int maxconn = 10; //最大连接
    int m_curconn;
    int m_freeconn;    //空闲连接
    
    locker Lock;     //原子操作
    sem rest;   //信号量类检测剩余空闲连接数
};


//真正实现RAII - 创建对象即获得一个连接, 析构函数则释放资源
class RAIIPool{
public:
    RAIIPool(MYSQL** conn, Pool* pool_);
    ~RAIIPool();
private:
    MYSQL* RAIIconn;
    Pool* RAIIpool;
};

具体实现:

Pool::Pool(){
    this->m_freeconn = 0;
    this->m_curconn = 0;
}

Pool::~Pool(){
    Destroy();
}

int Pool::getFreeconn(){
    return m_freeconn;
}

bool Pool::init(string url, string dbName, string dbPswd, string dbUser, int port){
    m_url = url;
    m_dbName = dbName;
    m_port = port;
    m_dbPswd = dbPswd;
    m_dbUser = dbUser;
    for(int i = 0; i < maxconn; ++i){
        MYSQL* conn = NULL;
        conn = mysql_init(conn);
        if(conn == NULL){
            perror("mysql_init");
            exit(1);
        }
        conn = mysql_real_connect(conn, url.c_str(), dbUser.c_str(), dbPswd.c_str(), dbName.c_str(), port, NULL, 0);
        if(conn == NULL){
            perror("mysql_real_connect");
            exit(1);
        }          
        pool_.push_back(conn);
        ++m_freeconn;
    }
    rest = sem(m_freeconn);
    return true;
}

void Pool::Destroy(){
    Lock.lock();
    for(auto it = pool_.begin(); it != pool_.end(); ++it){
        MYSQL* item = *it;
        mysql_close(item);
    }
    m_curconn = 0;
    m_freeconn = 0;
    pool_.clear();  //清空list
    list<MYSQL*>().swap(pool_); //释放资源
    Lock.unlock();
}

MYSQL* Pool::GetConn(){
    if(pool_.size() == 0){
        return nullptr;
    }
    Lock.lock();

    rest.wait();  //信号量-1
    MYSQL* conn = pool_.front(); //取出一个连接
    pool_.pop_front();
    --m_freeconn;
    ++m_curconn;
    
    Lock.unlock();
    return conn;
}

void Pool::releaseConn(MYSQL* conn){
    if(conn == NULL){
        return;
    }
    Lock.lock();

    pool_.push_back(conn); //放进空闲链接队列
    ++m_freeconn;
    --m_curconn;
    rest.post();  //信号量+1
    
    Lock.unlock();
}

Pool* Pool::getInstance(){
    static Pool conn;  //全类共享
    return &conn;
}


RAIIPool::RAIIPool(MYSQL** conn ,Pool* pool_){
    *conn = pool_->GetConn();

    RAIIconn = *conn;
    RAIIpool = pool_;
}

RAIIPool::~RAIIPool(){
    RAIIpool->Destroy();
}

locker类实现:

class locker
{
public:
    locker(){
        if(pthread_mutex_init(&mtx, nullptr) != 0){
            throw std::exception();
        }
    }
    ~locker(){
        pthread_mutex_destroy(&mtx);
    }
    bool lock(){
        return pthread_mutex_lock(&mtx) == 0;
    }
    bool unlock(){
        return pthread_mutex_unlock(&mtx) == 0;
    }
    pthread_mutex_t* GetMtx(){ //获取一把锁
        return &mtx;
    }
private:
    pthread_mutex_t mtx;
};

class sem
{
public:
    sem(int num){
        if(sem_init(&id, 0, num) != 0){  //线程共享
            throw std::exception();  
        }
    }
    sem(){
        if(sem_init(&id, 0, 0) != 0){
            throw std::exception();
        }
    }
    ~sem(){
        sem_destroy(&id);
    }
    bool wait(){
        return sem_wait(&id) == 0;
    }
    bool post(){
        return sem_post(&id) == 0;
    }
private:
    sem_t id;
};
mysql连接池实现 1.创建一个连接Mysql的线程池,作用是维持和管理固定数量与数据库的TCP长连接,实现资源复用,更快的系统响应。 阅读详情

相关推荐

C++ 连接池(基类), 被继承后可以兼容Mysql连接池和Redis连接池

程序类型: C++连接池抽象类 适用平台: Linux 适用数据库: Mysql(亲测可用), Redis(亲测可用), Oracle(亲测可用) 适合读者: C/C++初学者学习交流使用 使用注意: 此类属于C++抽象类, 必须被继承后使用 简单介绍: 这段时间开发服务器涉及到redis和mysql数据库连接池, 在网上翻阅资料基本上都是针对性的,比如针对mysql设计的mysql连接...

tonny7501的博客 818

剖析 MySQL 数据库连接池(C++版)

上次给大家介绍了线程池的实现,这次来介绍下 Linux 下数据库连接池的实现,以大家最为熟悉的MySQL为例,因为连接池总体实现还是较为复杂的,本次以一个开源框架的数据库连接池部分为例进行讲解。首先,服务器与数据库的交互是请求响应模式,通常所使用的是TCP 长连接,而 TCP 连接需要三次握手和四次挥手,并且每次连接都需要验证账号密码等,所以连接资源属于耗时资源,可以用连接池来复用连接。

新人博主,多多关照 2215

【C++】基于C++11的数据库连接池

在进行数据库操作的时候为了提高数据库(关系型数据库)的访问瓶颈,除了在服务器端增加缓存服务器(例如redis)缓存常用的数据之外,还可以增加连接池,来提高数据库服务器的访问效率。一般来说,对于数据库操作都是在访问数据库的时候创建连接,访问完毕断开连接。

IdealSanX的博客 1784

数据库连接池(七)

具体的,工作线程从数据库连接池取得一个连接,访问数据库中的数据,访问完毕后将连接交还连接池。从一般流程中可以看出,若系统需要频繁访问数据库,则需要频繁创建和断开数据库连接,而创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。当线程数量大于数据库连接数量时,使用信号量进行同步,每次取出连接,信号量原子减1,释放连接原子加1,若连接池内没有连接了,则阻塞等待。在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,更加安全可靠。

qq_59993282的博客 596

数据仓库实践:从ITR流程讲指标体系建设

从 ITR 流程或者其他客服反馈流程的考核过程可见,实际工作中不可能只通过单个指标评价一个业务过程,需要从多个维度梳理业务,并把多个高度相关的指标组织起来,以避免只考虑其中某个指标从而摧毁整个业务过程的结果,指标体系=指标+体系。

the_singing_towers的博客 2265

《UE4游戏开发》之 《音效系统的实现》

音效系统需要负责管理什么事情: 1.1 确定声音控制的分类:如背景音乐、技能音效、界面音效、角色配音等,不同游戏对声音有不同的分类 1.2 控制每个分类的声音的开启与关闭,以及调节每个分类声音的大小 解决如何分类: 2.1 首先需要知道ue4为声音分类提供了什么:SoundClass通常需要一个根分类【SC_RPG_Master】,便于总体控制音效,以及指定引擎默认启动的音效 打开SoundClass资产【SC_RPG_Master】,对根控制的设置,将逐级传递并按比例进行设置,以此达到控制一类声音的目的.

qq_21919621的博客 2126

数据库连接池的实现方法(MySQL+C++)

这里对数据库连接池的实现代码进行简单地总结。

liitdar的博客 9058

EMS案例:BMS传导发射超标整改案例

BMS作为新能源汽车的关键部件,其EMC性能直接影响整车的安全性和可靠性。本文通过一个实际的传导发射整改案例,详细展示了从问题定位、分析到解决方案实施的全过程。希望这些经验能够为从事类似产品设计的工程师提供有价值的参考,在未来的产品开发中避免类似问题,设计出更加可靠、稳定的BMS产品。EMC设计是一门结合理论与实践的艺术,只有通过不断积累经验、深入理解电磁场理论,并紧密结合实际应用场景,才能在复杂的电磁环境中设计出鲁棒性强的电子产品。

m0_56451176的博客 272

C++多线程数据库连接池MySQL

C++ 调用 MYSQL API 连接池 多线程

从事Android BSP 工程师,日常开发些APK,分享调试记录等信息 2287

SAP 中配置权限职责菜单并分配给用户的核心流程是:用PFCG 创建 / 维护角色(含菜单、事务码、权限)→ 生成权限参数文件 → 通过 SU01/SU10 将角色分配给用户

SAP权限配置核心流程:1)通过PFCG创建角色,配置菜单事务码及权限对象;2)生成权限参数文件;3)用SU01/SU10分配角色给用户。关键步骤包括:在PFCG中维护菜单结构、设置权限字段值、生成Profile,通过用户比较验证权限。批量分配可用SU10,特殊需求可创建复合角色或自定义权限对象。常见问题需检查权限缺失(SU53)、菜单分配及组织级别设置。流程简化为:创建角色→配置权限→分配用户→验证生效。

金牌架构师 1271

基于YOLOv26的护栏损坏检测系统原理讲解

本文介绍了一种基于YOLOv26深度学习的护栏损坏检测系统。该系统通过车载摄像头或固定监控采集道路护栏图像,利用改进的YOLOv26算法实现高效准确的损坏检测。系统采用分层架构设计,包含数据采集、检测处理、分析评估和应用服务四个层次,能够自动识别变形、断裂、缺失等五种常见损坏类型,并评估损坏严重程度。相比传统人工检测方法,该系统大幅提高了检测效率和准确性,降低了人工成本和安全风险。关键技术包括多尺度特征融合、注意力机制和自适应非极大值抑制等创新设计,使系统在复杂道路环境下仍能保持稳定的检测性能。

一键难忘的博客 327

C++实现MySQL数据库连接池

为了提升MysSQl数据库服务器的的并发能力,为此使用C++实现MySQL数据库连接池,提高并发能力。主要涉及技术有MySQL数据库编程、STL容器、单例模式、多线程互斥、同步通信、互斥锁、智能指针、lambda表达式等相关内容。

qq_45041871的博客 1916

【STM32系统】基于STM32设计的锂电池电量/电压检测报警器系统

本设计旨在研究一个基于STM32F103C8T6微控制器的锂电池电量/电压检测报警器系统,应用于便携式电子设备电池管理。系统通过STM32的ADC模块对18650锂电池电压进行采集,利用LCD1602显示模块实时显示电池电压,当检测到电池电量不足或电压异常时,蜂鸣器报警模块会发出警报提醒用户。系统采用简单的硬件结构和优化的软件架构,通过对实际电池电压数据的检测、处理和显示,实现了低功耗、实时监测的锂电池管理功能。本文将介绍系统的设计原理、硬件电路、软件实现以及调试测试过程。

嵌入式阿齐Archie 1万+

Mysql数据库连接池的简单实现(基于C++11), 基础学完, 包教包会.

Mysql数据库连接池的简单实现(基于C++11), 基础学完, 包教包会. 保姆级别教程, 作为简单上手项目再合适不过了

小杰312的博客 2009

【EDA Tools】Spyglass 检查 Verilog 和 SystemVerilog 混合语言及 Lint 检查

Spyglass可以用于检查混合设计中的语言互操作性和一致性问题。对于设计中包含多种硬件描述语言的情况,Spyglass 能够识别并解析其中的模块及其互连,并对其进行验证。例如,在包含 Verilog 和 VHDL 的混合设计中,Spyglass 会自动识别并解析 Verilog 和 VHDL 文件及其相互连接。通过运行 Spyglass Lint 功能,可以检查混合设计中的语言一致性问题,例如不兼容的数据类型、互操作性问题以及其他可能导致设计故障或不一致的问题。

记录学习历程 5076

单片机:实现简单的时间片轮询调度(附完整源码)

单片机:实现简单的时间片轮询调度(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 382

c mysql连接池_在LINUX下用C/C++写了一个连接池(访问MYSQL)的类

一、头文件【存为:connPool.h】#ifndef __CONNECTION_POOL_H__#define __CONNECTION_POOL_H__#include "mutex.h"#defineMYSQL_CONN_NUM_MAX_VALUE500using namespace std;enum _USE_STATUS{US_USE = 0,US_IDLE = 1};typedef...

weixin_39654352的博客 165

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C 连接mySql 连接池_在LINUX下用C/C++写了一个连接池(访问MYSQL)的类

一、头文件【存为:connPool.h】#ifndef __CONNECTION_POOL_H__#define __CONNECTION_POOL_H__#include "mutex.h"#defineMYSQL_CONN_NUM_MAX_VALUE500using namespace std;enum _USE_STATUS{US_USE = 0,US_IDLE = 1};typedef...

weixin_33905037的博客 140

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C MySql封装类 高性能连接池_在LINUX下用C/C++写了一个连接池(访问MYSQL)的类

一、头文件【存为:connPool.h】#ifndef __CONNECTION_POOL_H__#define __CONNECTION_POOL_H__#include "mutex.h"#defineMYSQL_CONN_NUM_MAX_VALUE500using namespace std;enum _USE_STATUS{US_USE = 0,US_IDLE = 1};typedef...

weixin_39867594的博客 184

C++ 如何实现mysql连接池?

网上大部分MySQL连接池实现都是玩具demo级别的,要么功能简陋,要么bug一堆,根本不能用于生产环境。作为一个写了好几年C++后端的程序员,我来详细聊聊如何实现一个真正可用的MySQL连接池。线程池卖爆了!这次直接上"王炸"——手撸4200行MySQL连接池,8天带你搞定后端核心组件!先说说痛点。直接连接MySQL的问题: 性能对比数据:这就是为什么所有互联网公司都必须用连接池的原因。 设计要点: 3. 智能重连机制 这是大多数demo实现忽略的关键点: 4. 健康检查线程 现有开源方案的问题 很多人

Henry313的博客 1250

C++ 实现 MySQL 连接池

C++ 实现 MySQL 连接池 复习

C/C++ 1226

MYSQL数据库连接池 | C++ | 项目实战

本文主要介绍数据库连接池实现的相关细节

m0_74795952的博客 2380

C++版mysql数据库连接池

手写数据库连接池 文章目录手写数据库连接池关键技术点项目背景连接池功能点介绍MySQL Server参数介绍功能实现设计连接池代码及详细介绍连接池构造函数获取单例生产者线程消费者线程接口定时线程(回收连接)压力测试测试代码和配置文件:Connection 操作代码 返回的 是一个含connection的shared_ptr对象 关键技术点 MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信(mutex、条件变量)和 unique_lock、基于CAS的原子整

qq_53111905的博客 2347

3.1.3 MYSQL连接池

3.1.3 MYSQL连接池

weixin_52423494的博客 2742
上一篇: leetcode关于“组合“的题目合集
下一篇: 基于C++写一个线程池
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值