分享
 
 
 

OCIEnvCreate()多线程初始化的模式问题

王朝vc·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

我最近才开始学习oci,看到有关多线程的部分时对于多线程情况下的mode参数设置有些疑问.

1.在 Oracle Call Interface Programmer's Guide 中这样写"In order to take advantage of thread safety, an application must be running on a thread-safe platform. Then the application must tell the OCI layer that theapplication is running in multithreaded mode, by specifying OCI_THREADED for the mode parameter of the opening call to OCIEnvCreate()."也就是说在多线程的程序中需要用OCI_THREADED.

2.而在oci本身自带的Multi-threading example中却是用OCI_DEFAULT

调用的OCIEnvCreate().

3.在文档中关于environment的mutex保护又有这样一段话

"The following three scenarios are possible, depending on how many connections exist in each environment handle, and how many threads will be spawned in each connection

1.If an application has multiple environment handles, but each only has one thread (one session exists in each environment handle), no mutexing is required.

2.If an application running in OCI_THREADED mode maintains one or more environment handles, each of which has multiple connections, it also has the following options:

Pass a value of OCI_NO_MUTEX for the mode of OCIEnvCreate(). In this case the application must mutex OCI calls by made on the same environment handle itself. This has the advantage that the mutexing scheme can be optimized based on the application design. The programmer must also insure that only one OCI call is in process on the environment handle connection at any given time.

Pass a value of OCI_DEFAULT to OCIEnvCreate(). In this case, the OCI library automatically gets a mutex on every OCI call on the same environment handle."

结合 2,3小第猜想如果在多线程的情况下如果每个env只包含一个数据库的连接,则不需要使用OCI_THREADED 来调用OCIEnvCreate().如果每个env包含多于一个的数据库连接则需要OCI_THREADED.

因为我刚开始看oci的东西,所以还没有写过半程序来测试,希望有相关经验的大侠拔刀相助.

希望感兴趣的人一起研究一下.要试这个问题首先要写连接程序,我用c++写了简单的连接类现在已经调试通过了,写的匆忙没有什么错误控制代码.贴出来给大家讨论,因为我是第一次写所以肯定有不少问题,现在也是没有办法啊.希望大侠出现啊.

h file

#ifndef __ORACONNECT_H__

#define __ORACONNECT_H__

#include

extern "C"

{

sword OCIEnvCreate (OCIEnv **envp, ub4 mode, dvoid *ctxp,

dvoid *(*malocfp)(dvoid *ctxp, size_t size),

dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize),

void (*mfreefp)(dvoid *ctxp, dvoid *memptr),

size_t xtramem_sz, dvoid **usrmempp);

}

class OraConnect

{

public:

OraConnect();

~OraConnect();

bool Connect();

bool DisConnect();

void setUsername(char* strusername);

void setPassword(char* strpassword);

void setDbname(char* strdbname);

void checkerr(OCIError *errhp,sword status);

protected:

private:

char username[128];

char password[128];

char dbname[128];

//Set the OCI variable

OCIEnv *envhp;

OCIError *errhp;

OCISession *authp;

OCIServer *srvhp;

OCISvcCtx *svchp;

};

#endif

.cpp file

#include "StdAfx.h"

#include "Connect.h"

OraConnect::OraConnect()

{

}

OraConnect::~OraConnect()

{

}

void

OraConnect::setUsername(char* strusername)

{

strcpy(username,strusername);

}

void

OraConnect::setPassword(char* strpassword)

{

strcpy(password,strpassword);

}

void

OraConnect::setDbname(char* strdbname)

{

strcpy(dbname,strdbname);

}

bool

OraConnect::Connect()

{

ub4 mode = OCI_SHARED|OCI_THREADED;

//ub4 mode=OCI_DEFAULT;

//Create the envirnment.

//(void) OCIEnvCreate(&envhp, mode, (CONST dvoid *)0, 0, 0, 0, (size_t)0, (dvoid **)0);

(void) OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0,(dvoid * (*)(dvoid *, size_t)) 0,(dvoid * (*)(dvoid *, dvoid *, size_t))0,(void (*)(dvoid *, dvoid *)) 0 );

(void) OCIEnvInit( (OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0,(dvoid **) 0 );

//Allocate the handle

(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0);

(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,(size_t) 0, (dvoid **) 0);

(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,(size_t) 0, (dvoid **) 0);

//Set the db link name.

(void) OCIServerAttach( srvhp, errhp, (text *)dbname, strlen(dbname), 0);

/* set attribute server context in the service context */

(void) OCIAttrSet( (dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp,(ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp);

(void) OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp,(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0);

(void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,(dvoid *) username, (ub4) strlen((char *)username),(ub4) OCI_ATTR_USERNAME, errhp);

(void) OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,(dvoid *) password, (ub4) strlen((char *)password),(ub4) OCI_ATTR_PASSWORD, errhp);

checkerr(errhp, OCISessionBegin ( svchp, errhp, authp, OCI_CRED_RDBMS,

(ub4) OCI_DEFAULT));

(void) OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,(dvoid *) authp, (ub4) 0,(ub4)OCI_ATTR_SESSION, errhp);

return true;

}

bool

OraConnect:isConnect()

{

if (errhp)

(void) OCIServerDetach( srvhp, errhp, OCI_DEFAULT );

if (srvhp)

checkerr(errhp, OCIHandleFree((dvoid *) srvhp, OCI_HTYPE_SERVER));

if (svchp)

(void) OCIHandleFree((dvoid *) svchp, OCI_HTYPE_SVCCTX);

if (errhp)

(void) OCIHandleFree((dvoid *) errhp, OCI_HTYPE_ERROR);

if(envhp)

(void) OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV);

return true;

}

void

OraConnect::checkerr(OCIError *errhp,sword status)

{

text errbuf[512];

sb4 errcode = 0;

switch (status)

{

case OCI_SUCCESS:

break;

case OCI_SUCCESS_WITH_INFO:

(void) printf("Error - OCI_SUCCESS_WITH_INFO\n");

break;

case OCI_NEED_DATA:

(void) printf("Error - OCI_NEED_DATA\n");

break;

case OCI_NO_DATA:

(void) printf("Error - OCI_NODATA\n");

break;

case OCI_ERROR:

(void) OCIErrorGet((dvoid *)errhp, (ub4) 1, (text *) NULL, &errcode,

errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);

(void) printf("Error - %.*s\n", 512, errbuf);

break;

case OCI_INVALID_HANDLE:

(void) printf("Error - OCI_INVALID_HANDLE\n");

break;

case OCI_STILL_EXECUTING:

(void) printf("Error - OCI_STILL_EXECUTE\n");

break;

case OCI_CONTINUE:

(void) printf("Error - OCI_CONTINUE\n");

break;

default:

break;

}

}

在调试中反而发现了一个怪问题,当我的mode设置成OCI_SHARED|OCI_THREADED,用OCIEnvCreate调用会crash,不过如果单用OCI_SHARED或OCI_THREADED就不会有问题,如果用

OCIInitialize和OCIEnvInit来替代OCIEnvCreate则没有什么问题,不过我觉得是我自己的编译参数不太对吧.我的环境是(oracle8.1.7,windows2000 professional,vc6(sp5)).

调用代码.

OraConnect conn[10];

for(int i=0;i

{

conn[i].setUsername("skyems");

conn[i].setPassword("skyems");

conn[i].setDbname("skydb");

conn[i].Connect();

}

for(int j=0;j

{

conn[j].DisConnect();

}

试了试,应该是没什么问题的.试了试,应该是没什么问题的.h file中的extern声明是因为oci是个c接口

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有