介绍
代码
管理已连接的连接用到双向链表 目录结构
double_llist.h
# ifndef DOUBLE_LLIST__
# define DOUBLE_LLIST__
typedef void d_llist_node_t ;
typedef void d_llist_t ;
int llist_init ( d_llist_t * * llist) ;
typedef int ( * compare) ( void * a, void * b) ;
int llist_insert ( d_llist_t * llist, void * key, compare cmp) ;
d_llist_node_t * llist_pop_first ( d_llist_t * llist) ;
d_llist_node_t * llist_pop_last ( d_llist_t * llist) ;
d_llist_node_t * llist_head_look ( d_llist_t * llist) ;
d_llist_node_t * llist_tail_look ( d_llist_t * llist) ;
int llist_destroy ( d_llist_t * llist) ;
typedef int ( * traver) ( void * node) ;
int llist_traver ( d_llist_t * llist, traver tvr) ;
int llist_check ( d_llist_t * llist, compare cmp) ;
d_llist_node_t * llist_find_node ( d_llist_t * llist, void * key, compare cmp) ;
int llist_delete_node ( d_llist_t * llist, void * key, compare cmp) ;
# endif
double_llist.c
# include <stdio.h>
# include <stdlib.h>
# include "./double_llist.h"
typedef struct llist_node_s {
void * key;
struct llist_node_s * prev;
struct llist_node_s * next;
} llist_node_t ;
typedef struct llist_s {
llist_node_t * head;
llist_node_t * tail;
} llist_t ;
int llist_init ( void * * llist) {
llist_t * me = NULL ;
me = ( llist_t * ) malloc ( sizeof ( * me) ) ;
if ( me == NULL ) {
return - 1 ;
}
me-> head = NULL ;
me-> tail = NULL ;
* llist = me;
return 0 ;
}
int llist_insert ( d_llist_t * llist, void * key, compare cmp) {
llist_t * me = llist;
llist_node_t * cur = me-> head;
llist_node_t * node_ = NULL ;
node_ = ( llist_node_t * ) malloc ( sizeof ( * node_) ) ;
if ( node_ == NULL ) {
return - 1 ;
}
node_-> next = NULL ;
node_-> prev = NULL ;
node_-> key = key;
int res = 0 ;
while ( cur != NULL ) {
res = cmp ( key, cur-> key) ;
if ( res > 0 ) {
cur = cur-> next;
} else {
break ;
}
}
if ( cur == NULL ) {
node_-> prev = me-> tail;
node_-> next = NULL ;
if ( me-> tail != NULL ) {
me-> tail-> next = node_;
me-> tail = node_;
} else {
me-> tail = node_;
}
if ( me-> head == NULL ) {
me-> head = node_;
}
} else if ( cur == me-> head) {
node_-> next = me-> head;
node_-> prev = NULL ;
me-> head-> prev = node_;
me-> head = node_;
} else {
node_-> next = cur;
node_-> prev = cur-> prev;
cur-> prev-> next = node_;
cur-> prev = node_;
}
return 0 ;
}
void * llist_pop_first ( void * llist) {
llist_t * me = llist;
llist_node_t * cur = me-> head;
if ( cur == NULL ) {
return NULL ;
} else if ( cur-> next == NULL ) {
me-> head = NULL ;
me-> tail = NULL ;
} else {
me-> head = cur-> next;
me-> head-> prev = NULL ;
}
void * ret = cur-> key;
free ( cur) ;
return ret;
}
void * llist_pop_last ( void * llist) {
llist_t * me = llist;
llist_node_t * cur = me-> tail;
if ( cur == NULL ) {
return NULL ;
} else if ( cur-> prev == NULL ) {
me-> head = NULL ;
me-> tail = NULL ;
} else {
me-> tail = cur-> prev;
me-> tail-> next = NULL ;
}
void * ret = cur-> key;
free ( cur) ;
return ret;
}
int llist_destroy ( void * llist) {
llist_t * me = llist;
llist_node_t * cur = me-> head, * temp = NULL ;
while ( cur != NULL ) {
temp = cur-> next;
free ( cur-> key) ;
free ( cur) ;
cur = temp;
}
free ( me) ;
llist = NULL ;
return 0 ;
}
int llist_traver ( void * llist, traver tvr) {
llist_t * me = llist;
llist_node_t * cur = me-> head;
while ( cur != NULL ) {
tvr ( cur-> key) ;
cur = cur-> next;
if ( cur) {
printf ( " -> " ) ;
}
}
printf ( "\n" ) ;
return 0 ;
}
int llist_check ( void * llist, compare cmp) {
llist_t * me = llist;
llist_node_t * cur = me-> head;
if ( cur != NULL && cur-> next != NULL ) {
cur = cur-> next;
} else {
return 0 ;
}
while ( cur != NULL ) {
if ( cmp ( cur-> key, cur-> prev-> key) < 0 ) {
return - 1 ;
}
cur = cur-> next;
}
return 0 ;
}
d_llist_node_t * llist_head_look ( d_llist_t * llist) {
llist_t * me = llist;
if ( me-> head == NULL ) {
return NULL ;
}
return me-> head-> key;
}
d_llist_node_t * llist_tail_look ( d_llist_t * llist) {
llist_t * me = llist;
if ( me-> tail == NULL ) {
return NULL ;
}
return me-> tail-> key;
}
d_llist_node_t * llist_find_node ( d_llist_t * llist, void * key, compare cmp) {
llist_t * me = llist;
llist_node_t * cur = me-> head;
int res = 0 ;
while ( 1 ) {
if ( cur == NULL ) {
return NULL ;
}
res = cmp ( key, cur-> key) ;
if ( res == 0 ) {
return cur;
}
cur = cur-> next;
}
return NULL ;
}
int llist_delete_node ( d_llist_t * llist, void * key, compare cmp) {
llist_t * me = llist;
llist_node_t * cur = llist_find_node ( llist, key, cmp) ;
if ( cur == NULL ) {
return - 1 ;
}
if ( cur-> prev == NULL && cur-> next == NULL ) {
me-> head = NULL ;
me-> tail = NULL ;
} else if ( cur-> prev == NULL ) {
me-> head = cur-> next;
me-> head-> prev = NULL ;
} else if ( cur-> next == NULL ) {
me-> tail = cur-> prev;
me-> tail-> next = NULL ;
} else {
cur-> next-> prev = cur-> prev;
cur-> prev-> next = cur-> next;
}
# if 1
free ( cur-> key) ;
free ( cur) ;
# endif
return 0 ;
}
connect_pool.h
# ifndef _CONNECT_POOL_H__
# define _CONNECT_POOL_H__
# include "pthread.h"
# include <mysql/mysql.h>
# include "../double_llist/double_llist.h"
typedef struct connect_pool_st {
d_llist_t * connect;
int connect_idel;
int connect_total;
pthread_mutex_t mutex;
char * host;
char * username;
char * passwd;
char * database;
short port;
} connect_pool_t ;
typedef struct sql_msg_st {
MYSQL * mysql;
MYSQL_ROW row;
MYSQL_RES * res;
} sql_msg_t ;
int connect_pool_init ( connect_pool_t * * pool, int conn_num, const char * host,
const char * username, const char * passwd, const char * database,
short port) ;
sql_msg_t * get_a_connection ( connect_pool_t * pool) ;
int return_a_connection ( connect_pool_t * pool, sql_msg_t * will) ;
int connect_pool_destroy ( connect_pool_t * pool) ;
# endif
connect_pool.c
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <pthread.h>
# include "./connect_pool.h"
static int my_compare ( void * a, void * b) {
return 1 ;
}
static int connect_init_ ( connect_pool_t * pool) {
connect_pool_t * me = pool;
int i = 0 ;
for ( i = 0 ; i < me-> connect_total; i++ ) {
sql_msg_t * cur = ( sql_msg_t * ) malloc ( sizeof ( * cur) ) ;
cur-> mysql = mysql_init ( NULL ) ;
if ( mysql_real_connect ( cur-> mysql, me-> host, me-> username, me-> passwd, me-> database, me-> port, NULL , 0 ) == 0 ) {
puts ( me-> host) ;
puts ( me-> username) ;
puts ( me-> passwd) ;
puts ( me-> database) ;
printf ( "port = %d\n" , me-> port) ;
printf ( "connect error.\n" ) ;
perror ( "connect()" ) ;
return - 1 ;
} else {
printf ( "[%d] connect success.\n" , i + 1 ) ;
}
cur-> res = NULL ;
cur-> row = NULL ;
llist_insert ( pool-> connect, cur, my_compare) ;
}
return 0 ;
}
int connect_pool_init ( connect_pool_t * * pool, int conn_num, const char * host,
const char * username, const char * passwd, const char * database,
short port) {
connect_pool_t * me = ( connect_pool_t * ) malloc ( sizeof ( * me) ) ;
if ( me == NULL ) {
return - 1 ;
}
llist_init ( & me-> connect) ;
me-> connect_total = conn_num;
me-> host = ( void * ) malloc ( strlen ( host) ) ;
strcpy ( me-> host, host) ;
me-> username = ( void * ) malloc ( strlen ( username) ) ;
strcpy ( me-> username, username) ;
me-> passwd = ( void * ) malloc ( strlen ( passwd) ) ;
strcpy ( me-> passwd, passwd) ;
me-> database = ( void * ) malloc ( strlen ( database) ) ;
strcpy ( me-> database, database) ;
me-> port = port;
pthread_mutex_t mutex_unused = PTHREAD_MUTEX_INITIALIZER;
memcpy ( & me-> mutex, & mutex_unused, sizeof ( mutex_unused) ) ;
connect_init_ ( me) ;
* pool = me;
return 0 ;
}
sql_msg_t * get_a_connection ( connect_pool_t * pool) {
connect_pool_t * me = pool;
pthread_mutex_lock ( & me-> mutex) ;
sql_msg_t * ret = llist_pop_first ( me-> connect) ;
pthread_mutex_unlock ( & me-> mutex) ;
return ret;
}
int return_a_connection ( connect_pool_t * pool, sql_msg_t * will) {
connect_pool_t * me = pool;
pthread_mutex_lock ( & me-> mutex) ;
int ret = llist_insert ( me-> connect, will, my_compare) ;
pthread_mutex_unlock ( & me-> mutex) ;
return ret;
}
int connect_pool_destroy ( connect_pool_t * pool) {
connect_pool_t * me = pool;
free ( me-> host) ;
free ( me-> username) ;
free ( me-> passwd) ;
free ( me-> database) ;
sql_msg_t * cur = NULL ;
while ( 1 ) {
pthread_mutex_lock ( & me-> mutex) ;
cur = llist_pop_first ( me-> connect) ;
pthread_mutex_unlock ( & me-> mutex) ;
if ( cur == NULL ) {
break ;
}
mysql_close ( cur-> mysql) ;
printf ( "A connection is closed.\n" ) ;
free ( cur) ;
}
free ( me) ;
pool = NULL ;
return 0 ;
}
test.c
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include "./connect_pool.h"
int my_traver ( void * a) {
printf ( "+" ) ;
return 0 ;
}
int main ( ) {
connect_pool_t * pool;
connect_pool_init ( & pool, 10 , "192.168.23.1" , "saika" , "1" , "test" , 3306 ) ;
sql_msg_t * cur = NULL ;
for ( int x = 0 ; x < 1024 ; x++ )
{
cur = get_a_connection ( pool) ;
if ( cur == NULL )
{
printf ( "without get.\n" ) ;
}
else
{
char * query = "select no from user;" ;
if ( mysql_real_query ( cur-> mysql, query, strlen ( query) ) != 0 )
{
printf ( "select false\n" ) ;
}
else
{
cur-> res = mysql_store_result ( cur-> mysql) ;
while ( ( cur-> row = mysql_fetch_row ( cur-> res) ) != NULL )
{
printf ( "%s\n" , * cur-> row) ;
}
}
}
}
llist_traver ( pool-> connect, my_traver) ;
return_a_connection ( pool, cur) ;
llist_traver ( pool-> connect, my_traver) ;
pause ( ) ;
connect_pool_destroy ( pool) ;
exit ( 0 ) ;
}
总结
已实现功能
获取一个连接 归还一个连接
待实现功能
对连接池内的连接数的动态增加和减少