自己写的一个基于ocilib的c连接池,未经测试

#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;
		}
	}
}


 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值