240717班级,工业化控制系统,煤矿相关行业,昆仑系统
Administrator
2024-11-06 731aab44a67db573ab7a9e6af8bfecf6efebbd23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "stdafx.h"
#include "ConnectionPool.h"
 
#include <fstream>
#include <iostream>
#include <thread>
 
ConnectionPool* ConnectionPool::getInstance() {
    static ConnectionPool connPool;
    return &connPool;
}
 
ConnectionPool::ConnectionPool() {
    // ¼ÓÔØÅäÖÃÎļþ
    if (!parseJsonFile()) {
        std::cout << "parseJsonFile is failed!" << std::endl;
        return;
    }
    for ( int i = 0 ; i < m_min_conn ; i++ ) {
        addConnection( );
    }
    // ´´½¨Ò»¸öỊ̈߳¬¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Á¬½ÓÊý²»×ã¾ÍÔÙ¼ÌÐø´´½¨
    std::thread producer(&ConnectionPool::produce, this);
    // ¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Èç¹ûÓÐÌ«¶à¿ÕÏеÃÏ̠߳£¬ÄÇô¾Í¶ÔÆä½øÐÐÏú»Ù
    std::thread recycler( &ConnectionPool::recycle,  this);
 
    // Ï̷߳ÖÀë
    producer.detach();
    recycler.detach();
}
 
bool ConnectionPool::parseJsonFile() {
 
    /*std::ifstream ifs("dbconf.json");
    Reader rd;
    Value root;
    rd.parse(ifs, root);
    if ( root.isObject( ) ) {
        m_ip = root["ip"].asString();
        m_port = root["port"].asInt();
        m_userName = root["userName"].asString();
        m_passwd = root["password"].asString();
        m_db = root["dbName"].asString();
        m_min_conn = root["minSize"].asInt();
        m_max_conn = root["maxSize"].asInt();
        max_del_time = root["maxDleTime"].asInt();
        m_timeout = root["timeout"].asInt();
        return true;
    }*/
    return false;
}
 
void ConnectionPool::description() {
    std::cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
               << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". " 
               << max_del_time << std::endl;
}
 
ConnectionPool::~ConnectionPool() {
    while (!m_connkQueue.empty()) {
        MysqlConn* conn = m_connkQueue.front();
        m_connkQueue.pop();
        delete  conn;
    }
 
}
 
void ConnectionPool::addConnection() {
    MysqlConn* conn = new MysqlConn();
    if ( !conn->connect( m_ip, m_userName, m_passwd, m_db, m_port  ) ) {
        std::cout << "ConnectionPool connect to mysql is failed!" << std::endl;
        delete conn;
        return;
    }
    conn->refreshActiveTime( );
    m_connkQueue.push(conn);
    m_cond.notify_one();   // »½ÐÑÒ»¸öÏß³Ì
}
 
void ConnectionPool::produce(){
    while (true) {
        std::unique_lock<std::mutex> lock(m_mutex);
        while (m_connkQueue.size() >= m_min_conn) { // Á¬½Ó¶ÓÁеÄÊýÁ¿´óÓÚ×îСµÄÁ¬½ÓÊý
            m_cond.wait(lock);
        }
        addConnection();
    }
}
 
// É¾³ý¿ÕÏÐÁ¬½Ó
void ConnectionPool::recycle() {
    while ( true ) {
        std::this_thread::sleep_for( std::chrono::milliseconds(500));   // ÐÝÃß500 ms
        std::unique_lock<std::mutex>lock(m_mutex);
        while ( m_connkQueue.size() > m_min_conn ) {
            MysqlConn* conn = m_connkQueue.front( );
            if (conn->getActiveTime() >= max_del_time) {
                m_connkQueue.pop();
                delete conn;
            }
            else {
                break;
            }
        }
    }
}
 
std::shared_ptr<MysqlConn>  ConnectionPool::getMysqlConn() {
    
    std::unique_lock<std::mutex>lock(m_mutex);
    while ( m_connkQueue.empty()) {
        // Èç¹ûµÈ´ýÒ»¶Îʱ¼äºó,¶ÓÁл¹ÊÇΪ¿Õ,·µ»ØÒ»¸ö null
        if ( std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_timeout)) ) {
            if( m_connkQueue.empty( ) )    return nullptr;
        }
    }
    std::shared_ptr<MysqlConn> connPtr(std::move(m_connkQueue.front()), [this](MysqlConn* conn) {
        std::unique_lock <std::mutex>lock(m_mutex) ;
        conn->refreshActiveTime();
        m_connkQueue.push(conn);
        });
    m_connkQueue.pop();
    m_cond.notify_one();   // »½ÐÑ×èÈûµÄÉú²úÕßÏß³Ì,¿ªÊ¼Éú²ú
    return connPtr;
}