自己写的一个基于ocilib的c连接池,未经测试
2011-11-25 09:11
435 查看
#include "ocilib.h" #include "pthread.h" #define DBFAIL -1 #define NOWAIT 1 #define WAITING 0 #define USE 0 #define NOUSE 1 typedef struct( OCI_Connection *cn; int status; //0-未用 1-使用中 TP_DBCONN_NODE *next; )TP_DBCONN_NODE; TP_DBCONN_NODE *g_header = NULL; int g_cur_conn_num = 0; int g_now_use_conn = 0; int g_min_conn; int g_max_conn; int g_incr_conn; char g_user[128] = {0}; char g_passwd[128]= {0}; char g_tns[128]= {0}; pthread_mutex_t conn_mutx; pthread_t pool_thread; int g_adjust_count = 0; //减少连接数的计数 int g_adjust_pecent = 80; //进行调度的比率 int g_adjust_threshold = 10; //进行调度的阈值 void oci_err_handler(OCI_Error *err) { printf( "code : ORA-%05i\n" "msg : %s\n" "sql : %s\n", OCI_ErrorGetOCICode(err), OCI_ErrorGetString(err), OCI_GetSql(OCI_ErrorGetStatement(err)) ); } int oci_db_pool_init(char *user, char *passwd, char *tns, int min_conn, int max_conn, int incr_conn) { TP_DBCONN_NODE *tmp_node = NULL; TP_DBCONN_NODE *pre_tmp_node = NULL; pthread_attr_t attr; int i; g_min_conn = min_conn; g_max_conn = max_conn; g_incr_conn = incr_conn; strncpy(g_user, user, sizeof(g_user) - 1); strncpy(g_passwd, passwd, sizeof(g_passwd) - 1); strncpy(g_tns, tns, sizeof(g_tns) - 1); pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 512000);//500K //初始化OCI if (!OCI_Initialize(oci_err_handler, NULL, OCI_ENV_DEFAULT|OCI_ENV_THREADED|OCI_ENV_CONTEXT)) return DBFAIL; //初始化数据库连接 for (i = 0; i < min_conn; i++) { pre_tmp_node = tmp_node; tmp_node = malloc(sizeof(TP_DBCONN_NODE)); memset((void *)tmp_node, 0, sizeof(TP_DBCONN_NODE)); tmp_node->cn = OCI_ConnectionCreate(tns, user, passwd, OCI_SESSION_DEFAULT); if (tmp_node->cn == NULL) { free(tmp_node); oci_db_pool_free(); return DBFAIL; } if (i == 0)//头节点 g_header = tmp_node; else//非头节点 pre_tmp_node->next = tmp_node; //TODO cur_conn_num++; } if (pthread_mutex_init(&conn_mutx, NULL) != 0) { oci_db_pool_free(); return DBFAIL; } //创建连接池守护线程 if (pthread_create(&pool_thread, &attr, (void *)db_pool_run, NULL) != 0) printf("pthread_create error\n"); } int oci_db_pool_free() { TP_DBCONN_NODE *tmp_node = g_header; TP_DBCONN_NODE *pre_tmp_node = NULL; while (tmp_node != NULL) { pre_tmp_node = tmp_node; tmp_node = tmp_node->next; //断开数据库连接 OCI_ConnectionFree(pre_tmp_node->cn); //释放内存 free(pre_tmp_node); } cur_conn_num = 0; g_header = NULL; OCI_Cleanup(); pthread_mutex_destory(&conn_mutx); } //增加一个数据库连接 OCI_Connection *oci_db_add_conn(int type) { TP_DBCONN_NODE *tmp_node = NULL; TP_DBCONN_NODE *pre_tmp_node = NULL; //加锁 if (pthread_mutex_lock(&conn_mutx) != 0) { return NULL; } //寻找最后一个节点 tmp_node = g_header; while (tmp_node->next != NULL) { tmp_node = tmp_node->next; if (tmp_node == NULL) break; } if (tmp_node != NULL) { pre_tmp_node = tmp_node; tmp_node = malloc(sizeof(TP_DBCONN_NODE)); memset((void *)tmp_node, 0, sizeof(TP_DBCONN_NODE)); tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT); if (tmp_node->cn == NULL) { free(tmp_node); tmp_node = NULL; }else { if (g_header == NULL)//头节点 g_header = tmp_node; else//非头节点 pre_tmp_node->next = tmp_node; tmp_node->status = type; g_cur_conn_num++; } }else tmp_node = NULL; //释放锁 if (pthread_mutex_unlock(&conn_mutx) != 0) { return NULL; } return tmp_node; } //减少一个数据库连接 int oci_db_del_conn() { TP_DBCONN_NODE *tmp_node = NULL; TP_DBCONN_NODE *pre_tmp_node = NULL; int ret; //加锁 if (pthread_mutex_lock(&conn_mutx) != 0) { return NULL; } tmp_node = g_header; //释放连接 while (tmp_node->stauts != 0) { pre_tmp_node = tmp_node; tmp_node = tmp_node->next; if (tmp_node == NULL) break; } if (tmp_node != NULL) { //断开数据库连接 OCI_ConnectionFree(tmp_node->cn); if (tmp_node == g_header) { g_header = g_header->next; free(tmp_node); }else { pre_tmp_node->next = tmp_node->next; free(tmp_node); } g_cur_conn_num--; ret = 0; }else ret = -1; //释放锁 if (pthread_mutex_unlock(&conn_mutx) != 0) { return NULL; } return ret; } /* 0-WAITING 1-NOWAIT */ OCI_Connection *oci_db_get_conn(int type) { TP_DBCONN_NODE *tmp_node = NULL; OCI_Connection *cn = NULL; //获取锁 if (type == NOWAIT) { if (pthread_mutex_trylock(&conn_mutx) != 0) return NULL; }else { if (pthread_mutex_lock(&conn_mutx) != 0) return NULL; } tmp_node = g_header; //查找现有列表获取连接 while (tmp_node->status != 0) { tmp_node = tmp_node->next; if (tmp_node == NULL) break; } //在现有连接中找到 if (tmp_node != NULL) { cn = tmp_node->cn; tmp_node->status = 1; if ((oci_db_test_conn(tmp_node->cn) != TRUE) //查询失败? { OCI_ConnectionFree(tmp_node->cn); tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT); if (tmp_node->cn == NULL) { tmp_node->status = 2; } } g_now_use_conn++; }else //未找到 已满? { //新增数据库连接 if (g_cur_conn_num < g_max_conn) { cn = oci_db_add_conn(USE); } } //释放锁 if (pthread_mutex_unlock(&conn_mutx) != 0) { return NULL; } return cn; } //释放一个连接 int oci_db_free_conn(OCI_Connection *cn) { TP_DBCONN_NODE *tmp_node = NULL; //加锁 if (pthread_mutex_lock(&conn_mutx) != 0) { return NULL; } tmp_node = g_header; //释放连接 while (cn != tmp_node->cn) { tmp_node = tmp_node->next; if (tmp_node == NULL) break; } tmp_node->status = 0; g_now_use_conn--; //释放锁 if (pthread_mutex_unlock(&conn_mutx) != 0) { return NULL; } } //检测连接 int oci_db_test_conn(OCI_Connection *cn) { OCI_Statement *st; int ret; st = OCI_StatementCreate(cn); ret = OCI_ExecuteStmt(st, "select 1 from dual;"); OCI_StatementFree(st); return ret; } //检测活跃状态 int oci_db_active_test() { TP_DBCONN_NODE *tmp_node = NULL; while (tmp_node != NULL) { if (tmp_node->status != 1) { if ((oci_db_test_conn(tmp_node->cn) != TRUE) //查询失败? { OCI_ConnectionFree(tmp_node->cn); tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT); if (tmp_node->cn == NULL) { tmp_node->status = 2; } } } tmp_node = tmp_node->next; } } static void db_pool_run(void * args) { while(1) { sleep(10); oci_db_active_test(); if ((g_now_use_conn *100 / g_cur_conn_num) < g_adjust_pecent) g_adjust_count++; else g_adjust_count = 0; if (g_adjust_count > g_adjust_threshold) { oci_db_del_conn(); g_adjust_count = 0; } } }
相关文章推荐
- 自己写的一个测试函数执行效率的单元(test on Delphi 7)
- 使用caffe训练并且测试一个自己的模型
- 自己早期做的一个基于j2me的魔塔
- 在自己的web项目中添一个连接池
- 【报表】一个在自己本机测试运行通过的RS脚本
- 一个有意思的测试,看看什么样的Linux发行版最适合自己!我的测试结果是:Debian !
- 用简单的驱动,自己写一个连接池
- 非要自己开发一个测试工具不可?
- 非要自己开发一个测试工具不可?
- 【数据库开发】如何创建MySQL数据库连接池(一个基于libmysql的MySQL数据库连接池示例(C/C++版))
- 一个基于epoll的服务器压力测试的小程序
- Objective-C如何自己实现一个基于数组下标的属性访问模式
- 一个基于STL的ini文件解析类,测试通过
- 基于JUnit 3.8 的一个简单的测试程序
- 自己写的一个基于C++的跨平台的轻量级日志类
- 使用caffe训练并且测试一个自己的模型
- 自己早期做的一个基于j2me的飞行射击类游戏
- 自己设计一个简单的的Java连接池(二)
- # 编写一个master - worker 进程管理模型 Ps :撇开一切web server的束缚, 自己设计自己测试 #
- 基于Nginx实现一个自己的HTTP模块--发送磁盘中的文件