国产探花免费观看_亚洲丰满少妇自慰呻吟_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接口

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 太湖县| 德惠市| 涟水县| 上杭县| 志丹县| 英德市| 合作市| 会同县| 新河县| 诏安县| 华安县| 临猗县| 屏南县| 寿阳县| 通榆县| 大悟县| 普宁市| 霍州市| 东乌珠穆沁旗| 五常市| 壤塘县| 鄯善县| 姜堰市| 青河县| 资中县| 南昌市| 阳西县| 榆中县| 贡嘎县| 云和县| 梁河县| 车致| 盐源县| 项城市| 岱山县| 定兴县| 青田县| 仪征市| 锡林郭勒盟| 鄂伦春自治旗| 马公市|