国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

OCIEnvCreate()多線程初始化的模式問題

2024-07-21 02:38:18
字體:
來源:轉載
供稿:網友

  我最近才開始學習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_SHAREDOCI_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_SHAREDOCI_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<10;i++)
  {
  conn[i].setUsername("skyems");
  conn[i].setPassword("skyems");
  conn[i].setDbname("skydb");
  conn[i].Connect();
  }
  
  for(int j=0;j<10;j++)
  {
  conn[j].DisConnect();
  }
  試了試,應該是沒什么問題的.試了試,應該是沒什么問題的.h file中的extern聲明是因為oci是個c接口

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安阳县| 河东区| 黑龙江省| 册亨县| 威宁| 兰坪| 阿尔山市| 赤水市| 天祝| 徐州市| 青阳县| 南丰县| 南城县| 闵行区| 公安县| 班玛县| 奉贤区| 五河县| 牡丹江市| 桃江县| 亳州市| 盐城市| 霍山县| 彰化县| 霍州市| 香港| 江川县| 云龙县| 安阳市| 舞钢市| 婺源县| 庆城县| 铁岭市| 宜都市| 青海省| 马龙县| 扬中市| 彝良县| 永年县| 岐山县| 吉林省|