400网站建设推广wordpress 侵权

当前位置: 首页 > news >正文

400网站建设推广,wordpress 侵权,mysql8.0 wordpress,阿里云搭建网站目背景 常见的MySQL、Oracle、SQLServer等数据库都是基于C/S架构设计的#xff0c;即#xff08;客户端/服务器#xff09;架构#xff0c;也就是说我们对数据库的操作相当于一个客户端#xff0c;这个客户端使用既定的API把SQL语句通过网络发送给服务器端#xff0c;MyS…目背景 常见的MySQL、Oracle、SQLServer等数据库都是基于C/S架构设计的即客户端/服务器架构也就是说我们对数据库的操作相当于一个客户端这个客户端使用既定的API把SQL语句通过网络发送给服务器端MySQL Server执行完SQL语句后将结果通过网络返回客户端。通过网络通信的话就要涉及到TCP/IP协议里的“三次握手”、“四次挥手”等大量访问时每一个用户的请求都会对应一次“三次握手”、“四次挥手”的过程这个性能的消耗是相当严重的 对于数据库本质上是对磁盘的操作如果对数据库的访问过多即I/O操作过多会出现访问瓶颈。 而常见的解决数据库访问瓶颈的方法有两种 一、为减少磁盘 I/O的次数在数据库和服务器的应用中间加一层 缓存数据库例如Redis、Memcache; 二、增加 连接池来减少高并发情况下大量 TCP三次握手、MySQL Server连接认证、MySQL Server关闭连接回收资源和TCP四次挥手 所耗费的性能。 mysqlconn.hpp 实现连接 增删改查操作 #include mysql/mysql.h #include iostream #include string #include ctime #include chrono #include memory #define INFO 1 #define WARNING 2 #define ERROR 3 #define FATAL 4#define LOG(level, message) Log(#level, message, FILE, LINE)void Log(std::string level, std::string message, std::string file_name, int line) {std::cout[level][time(nullptr)][message][file_name][line]std::endl; }class mysqlconn{private:MYSQL m_conn nullptr;MYSQL_RES m_res nullptr;//查询结果集MYSQL_ROW m_row;//记录结构体void freeResult(){if(m_res){mysql_free_result(m_res);m_res nullptr;}}std::chrono::steady_clock::time_point m_aliveTime;public:mysqlconn(){//获取一个MYSQL句柄m_conn mysql_init(nullptr);//设置字符集mysql_set_character_set(m_conn,utf8);}~mysqlconn(){freeResult();if(m_conn ! nullptr){mysql_close(m_conn);}}bool query(std::string sql){freeResult();if(mysql_query(m_conn, sql.c_str())){return false;}m_res mysql_store_result(m_conn);return true;}//更新 修改 删除bool update(std::string sql){return mysql_query(m_conn, sql.c_str());}//连接指定的数据库bool connect(std::string ip, std::string user, std::string passwd, std::string dbName, unsigned int port){return mysql_real_connect(m_conn, ip.c_str(), user.c_str(), passwd.c_str(), dbName.c_str(), port,nullptr,0) ! nullptr;}//遍历得到的结果集bool next(){if(m_res ! nullptr){m_row mysql_fetch_row(m_res); //获取一行if(m_row ! nullptr){return true;}}return false;}//获取结果集里的值std::string value(int index){int rowCount mysql_num_fields(m_res); //返回结果集中字段数目if(index rowCount || index 0){return std::string();}char* ans m_row[index];unsigned long length mysql_fetch_lengths(m_res)[index];return std::string(ans,length); }//事务处理提交方式bool transaction(){return mysql_autocommit(m_conn,false);}//事务提交bool commit(){return mysql_commit(m_conn);}//事务回滚bool rollback(){return mysql_rollback(m_conn);}//更新空闲时间点void refreshAliveTime(){m_aliveTime std::chrono::steady_clock::now();}//计算连接空闲时长long long getAliveTime(){std::chrono::durationdouble diff std::chrono::steady_clock::now() - m_aliveTime; //nanosecods 纳秒return diff.count();}};connpool.hpp 连接池 #include mutex #include condition_variable #include queue #include fstream #include thread#include mysqlconn.hppclass ConnectionPool {private:std::string m_user;std::string m_passwd;std::string m_ip;std::string m_dbName;unsigned short m_port;//连接的上限和下限,自动维护线程池的连接数int m_minSize;int m_maxSize;//连接的超时时长int m_timeout;int m_maxIdleTime;//线程同步 std::mutex m_mutexQ; //互斥锁std::condition_variable m_cond; //条件变量std::queuemysqlconn * m_connectionQ; //共享资源public://对外接口,获取线程池//静态局部变量是线程安全的static ConnectionPool *getConnectPool() {static ConnectionPool pool;return pool;}//获取线程池中的连接std::shared_ptrmysqlconn getConnection(){//需要操作共享资源std::unique_lockstd::mutex locker(m_mutexQ);//判断连接池队列为空while(m_connectionQ.empty()){if(std::cv_status::timeout m_cond.wait_for(locker, std::chrono::milliseconds(m_timeout))){if(m_connectionQ.empty()){continue;}}}//自定义shared_ptr析构方法,重新将连接放回到连接池中,而不是销毁std::shared_ptrmysqlconn connptr(m_connectionQ.front(),this{std::unique_lockstd::mutex locker(m_mutexQ);conn-refreshAliveTime();m_connectionQ.push(conn); });//弹出,放到了队尾m_connectionQ.pop();m_cond.notify_all();return connptr;}//防止外界通过拷贝构造函数和移动拷贝构造函数ConnectionPool(const ConnectionPool obj) delete;ConnectionPool operator(const ConnectionPool obj) delete;~ConnectionPool(){while(!m_connectionQ.empty()){mysqlconn *conn m_connectionQ.front();m_connectionQ.pop();delete conn;}} private://构造函数私有化ConnectionPool(){//加载配置文件if(!parseJsonFile()){return;}//创建最少连接数for(int i0;im_minSize;i){addConnect();}//创建子线程用于检测并创建新的连接std::thread producer(ConnectionPool::produceConnection,this);//销毁连接,检测并销毁连接std::thread recycler(ConnectionPool::recycleConnection,this);//设置线程分离producer.detach();recycler.detach();}//解析配置文件bool parseJsonFile(){ //可以通过配置文件配置数据 这里写死 m_ip 127.0.0.1;m_user pig;m_passwd test1234;m_dbName test;m_port 3306;m_minSize 10;m_maxSize 100;m_timeout 10;m_maxIdleTime 20;return true;}//任务函数void produceConnection() //生产数据库连接{//通过轮询的方式不断的去检测while(true) {//操作共享资源,需要加锁std::unique_lockstd::mutex locker(m_mutexQ);//判断连接数是否达到容量,如果大于等于容量则需要阻塞一段时间while (m_connectionQ.size() m_maxSize) {m_cond.wait(locker);}addConnect();m_cond.notify_all(); //唤醒消费者}}void recycleConnection() //销毁数据库连接{while(true){//休眠一定的时长std::this_thread::sleep_for(std::chrono::milliseconds(500));std::unique_lockstd::mutex locker(m_mutexQ);//让线程池中最少保持用于 m_minSize个线程while(m_connectionQ.size() m_minSize){mysqlconn *recyConn m_connectionQ.front();//如果超时则销毁if(recyConn-getAliveTime() m_maxIdleTime){m_connectionQ.pop();delete recyConn;} else{break;}}}}void addConnect() //添加连接{mysqlconn *conn new mysqlconn;conn-connect(m_ip,m_user,m_passwd,m_dbName,m_port);conn-refreshAliveTime();m_connectionQ.push(conn);}};main.cpp 测试主函数 单线程 连接池 多线程连接池 #include connpool.hppvoid pthread1_no_pool() {clock_t begin clock();std::unique_ptrmysqlconn sp std::make_uniquemysqlconn();bool connflag sp-connect(127.0.0.1,pig,test1234, test,3306);if(connflag false) return;for (int i 0; i 4 * 1000; i){sp-refreshAliveTime();char sql[1024] { 0 };sprintf(sql, insert into tb_file values(%d,%s,%s);,i, pthread1_no_pool, 1.png);auto upflag sp-update(sql);}clock_t end clock();std::cout pthread1_no_pool: (end - begin) ms std::endl;}void pthread1_use_pool(){ConnectionPool *cp ConnectionPool::getConnectPool();clock_t begin clock();std::shared_ptrmysqlconn sp cp-getConnection();for (int i 0; i 1000 * 4; i){char sql[1024] { 0 };sprintf(sql, insert into tb_file(id, name, file) values(%d,%s,%s);,i, pthread1_use_pool, 1.png);sp-update(sql);}clock_t end clock();std::cout pthread1_use_pool: (end - begin) ms std::endl;}void pthread4_no_pool() {clock_t begin clock();std::thread tt[4];for(int n 0; n 4; n){tt[n] std::thread([]{std::unique_ptrmysqlconn sp std::make_uniquemysqlconn();sp-connect(127.0.0.1,pig,test1234, test,3306);for (int i 0; i 1000 * (n 1); i){sp-refreshAliveTime();char sql[1024] { 0 };sprintf(sql, insert into tb_file values(%d,%s,%s);,i, pthread1_no_pool, 1.png);sp-update(sql);}});}for(int i 0; i 4; i){tt[i].join();}clock_t end clock();std::cout pthread4_no_pool: (end - begin) ms std::endl;}void work(ConnectionPool *cp , int l){std::shared_ptrmysqlconn sp cp-getConnection();for (int i l * 1000; i 1000 * (l 1); i){char sql[1024] { 0 };sprintf(sql, insert into tb_file values(%d,%s,%s);,i, pthread1_use_pool, 1.png);auto upflag sp-update(sql);if(upflag ! 0){std::cout pthread4_use_pool: upflag sql std::endl;continue;}} }void pthread4_use_pool() {ConnectionPool *cp ConnectionPool::getConnectPool();clock_t begin clock();std::thread tt[4];for(int i 0; i 4; i){tt[i] std::thread(work, cp, i);}for(int i 0; i 4; i){tt[i].join();}clock_t end clock();std::cout pthread4_use_pool: (end - begin) ms std::endl; }// g -o main main.cpp connpool.hpp mysqlconn.hpp -lmysqlclient -stdc14 -lpthread int main() {/单线程 不使用连接池///LOG(INFO, pthread1_no_pool test:);//pthread1_no_pool();/单线程 使用连接池///LOG(INFO, pthread1_use_pool test:);//pthread1_use_pool();/多线程 不使用连接池/LOG(INFO, pthread4_no_pool test:);pthread4_no_pool();/多线程 使用连接池///LOG(INFO, pthread4_use_pool test:);//pthread4_use_pool();return 0; } 单线程 无连接池 4000条数据插入 单线程 连接池 4000条数据插入 4线程 无连接池
4线程 连接池
测试结果 和预期一样 多线程下使用连接池中的连接 比重复建立连接快很多 ![结果](https://img-blog.csdnimg.cn/direct/5b15db6b9ade48b5b6f65b061a45b200.png参考 https://zhuanlan.zhihu.com/p/616675628