240717班级,工业化控制系统,煤矿相关行业,昆仑系统
wxx
2024-11-09 7ae42e0228e151b501b2e04fa32cc295851057b2
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
#include "stdafx.h"
#include "ConnectionPool.h"
 
 
ConnectionPool::ConnectionPool() {
 
 
    m_min_conn = 5; // ¼ÙÉè×îСÁ¬½ÓÊýΪ 5
    m_max_conn = 10; // ¼ÙÉè×î´óÁ¬½ÓÊýΪ 10
    m_timeout = 1000; // ¼ÙÉèÁ¬½Ó³¬Ê±Ê±¼äΪ 1000 ºÁÃë
    max_del_time = 60000; // ¼ÙÉè×î´ó¿ÕÏÐʱ¼äΪ 60000 ºÁÃë
 
    for (int i = 0; i < m_min_conn; i++) {
        addConnection();
    }
    // ´´½¨Ò»¸öỊ̈߳¬¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Á¬½ÓÊý²»×ã¾ÍÔÙ¼ÌÐø´´½¨
    thread producer(&ConnectionPool::produce, this);
    // ¶ÔÁ¬½ÓÊý½øÐÐ¼à¿Ø £¬Èç¹ûÓÐÌ«¶à¿ÕÏеÃÏ̠߳£¬ÄÇô¾Í¶ÔÆä½øÐÐÏú»Ù
    thread recycler(&ConnectionPool::recycle, this);
 
    // Ï̷߳ÖÀë
    producer.detach();
    recycler.detach();
}
 
 
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->isConnected()) {
        cout << "ConnectionPool connect to mysql is failed!" << endl;
        delete conn;
        return;
    }
    conn->refreshActiveTime();
    m_connkQueue.push(conn);
    m_cond.notify_one();   // »½ÐÑÒ»¸öÏß³Ì
}
 
void ConnectionPool::produce() {
    while (true) {
        unique_lock<mutex> lock(m_mutex);
        while (m_connkQueue.size() >= m_min_conn) { // Á¬½Ó¶ÓÁеÄÊýÁ¿´óÓÚ×îСµÄÁ¬½ÓÊý
            m_cond.wait(lock);
        }
        addConnection();
    }
}
 
// É¾³ý¿ÕÏÐÁ¬½Ó
void ConnectionPool::recycle() {
    while (true) {
        this_thread::sleep_for(chrono::milliseconds(500));   // ÐÝÃß 500 ms
        unique_lock<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;
            }
        }
    }
}
 
shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() {
    unique_lock<mutex> lock(m_mutex);
    while (m_connkQueue.empty()) {
        // Èç¹ûµÈ´ýÒ»¶Îʱ¼äºó,¶ÓÁл¹ÊÇΪ¿Õ,·µ»ØÒ»¸ö null
        if (cv_status::timeout == m_cond.wait_for(lock, chrono::milliseconds(m_timeout))) {
            if (m_connkQueue.empty()) return nullptr;
        }
    }
    shared_ptr<MysqlConn> connPtr(move(m_connkQueue.front()), [this](MysqlConn* conn) {
        unique_lock<mutex> lock(m_mutex);
        conn->refreshActiveTime();
        m_connkQueue.push(conn);
        });
    m_connkQueue.pop();
    m_cond.notify_one();   // »½ÐÑ×èÈûµÄÉú²úÕßÏß³Ì,¿ªÊ¼Éú²ú
    return connPtr;
}
void ConnectionPool::description() {
    cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
        << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
        << max_del_time << endl;
}
 
ConnectionPool* ConnectionPool::getInstance() {
    static ConnectionPool connPool;
    return &connPool;
}