源码:链接:https://pan.baidu.com/s/1y0F3YrFfsZgDRe6g6r4RMg 密码:vg2m
引言:数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个; 连接池技术大多运用在高并发服务器的后面;在现有的大型高并发服务器上,每一次线程与数据库的数据交换都属于网络连接,频繁的启停连接是极不合理的,特别是在大型Web服务器上过长时间的延迟在用户体验上极其糟糕,而重复的建立与断开数据库连接对程序的运行也有相当大的影响;
连接池是一个抽象的概念,它包含了一堆数据库连接、连接管理线程、对外提供的接口;
1.线程通过调用连接池接口获得一个数据库连接,使用后无需销毁连接,只需要在逻辑上放弃连接;当下一个线程获取时仍然能够正常使用;
2.连接池管理线程动态的对数据库连接进行管理,合理的增删,在满足外来调用的基础上保证连接数量的合理利用, 它就像一个吝啬的雇主; 增加和删除都会改变连接池的当前的状态,所以在下图数据库连接部池分的互斥锁将保证对状态操作的唯一性;
3.数据库连接应该在使用线程上加互斥锁,即使我们有十个使用了连接的线程,但在同一时间对同一个数据的修改我们也应该保证只有一个线程在操作,该功能在下图的线程部分中的互斥锁实现;
该图为一个简单的连接池实现模型,我们将以该图来实现一个最基础的连接池,该数据库采用MySQL
一、数据库连接池的抽象结构体(圆圈1)
#define IP_LEN 15
#define DBNAME_LEN 64
#define DBUSER_LEN 64
#define PASSWD_LEN 64
#define POOL_MAX_NUMBER 20
typedef struct _SQL_NODE SQL_NODE; /* 连接节点 */
typedef struct _SQL_CONN_POOL SQL_CONN_POOL; /* 连接池 */
/* 连接节点 */
typedef struct _SQL_NODE{
MYSQL fd; /* MYSQL对象文件描述符 */
MYSQL *mysql_sock; /* 指向已经连接的MYSQL的指针 */
pthread_mutex_t lock; /* 互斥锁; 用在线程对数据的操作限制*/
int used; /* 使用标志 */
int index; /* 下标 */
enum{ /* 连接状态 */
DB_DISCONN, DB_CONN
}sql_state;
}SQL_NODE;
/* 连接池 */
typedef struct _SQL_CONN_POOL{
int shutdown; /* 是否关闭 */
SQL_NODE sql_pool[POOL_MAX_NUMBER]; /* 一堆连接 */
int pool_number; /* 连接数量 */
int busy_number; /* 被获取了的连接数量 */
char ip[IP_LEN+1]; /* 数据库的ip */
int port; /* 数据库的port,一般是3306 */
char db_name[DBNAME_LEN+1]; /* 数据库的名字 */
char user[DBUSER_LEN+1]; /* 用户名 */
char passwd[PASSWD_LEN+1]; /* 密码 */
}SQL_CONN_POOL;
二、函数概况 (圆圈3) : 服务器创建连接池(创建节点),分配连接到线程,处理并归还;
/*创建连接池*/
SQL_CONN_POOL *sql_pool_create(int connect_pool_number, char ip[