본문 바로가기
배워야 산다/Pro-c

thread 를 이용한 pro*c (proc) 공식 예제

by 인라인타지마 2013. 1. 24.

thread 를 이용한 pro*c (proc) 공식 예제... 



Pro*C precompile 옵션에, THREADS=YES 추가해서, Thread safe 하게 해줘야 함.
ex:  PROCFLAGS= char_map=string parse=none THREADS=YES def_sqlcode=yes include=/usr/include


/* 
*  cpdemo1.pc 

* Description: 
*            The program creates as many sessions as there are threads. 
*      Each thread connects to the default database and executes 5 times 
*      SELECT statement. And each thread have its own runtime contexts. 

*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sqlca.h> 

#define      _EXC_OS_        _EXC__UNIX 
#define      _CMA_OS_        _CMA__UNIX 

#ifdef DCE_THREADS
#include <pthread.h>
#else
#include <pthread.h> 
typedef void*       pthread_addr_t;
typedef void*      (*pthread_startroutine_t) (void*);
#define pthread_attr_default  (const pthread_attr_t *)NULL
#endif

/* Function prototypes */ 
void   err_report(); 
void   do_transaction(); 
void   get_transaction(); 
void   logon(); 
void   logoff(); 

#define CONNINFO "hr/hr" 
#define THREADS  40 

struct parameters 
  { 
   sql_context * ctx;                         /* 근데 이거 포인터 선언했다???  */
   int thread_id; 
  }; 
typedef struct parameters parameters; 

struct timeval tp1;
struct timeval tp2;

/*************************************** 
*  Main 
***************************************/ 

main() 

  sql_context ctx[THREADS]; 
  pthread_t thread_id[THREADS]; 
  pthread_addr_t status; 
  parameters params[THREADS]; 
  int i; 

  EXEC SQL ENABLE THREADS; 
  EXEC SQL WHENEVER SQLERROR DO err_report(sqlca); 

  if(gettimeofday(&tp1, (void*)NULL) == -1)
  {
    perror("First: ");
    exit(0);
  }

  /* Create THREADS sessions by connecting THREADS times */ 
  for(i=0;i<THREADS;i++) 
  { 
    printf("Start Session %d....",i); 
    EXEC SQL CONTEXT ALLOCATE :ctx[i]; 
    logon(ctx[i],CONNINFO); 
  } 

  /*Spawn threads*/ 
  for(i=0;i<THREADS;i++) 
  { 
    params[i].ctx=ctx[i]; 
    params[i].thread_id=i; 
/* typedef void*       pthread_addr_t;  즉 (void *) & params[i] */
    if (pthread_create(&thread_id[i],pthread_attr_default,
      (pthread_startroutine_t)do_transaction,
      (pthread_addr_t) & params[i]))
      printf("Cant create thread %d\n",i); 
    else 
      printf("Created Thread %d\n", i); 
  } 

  /* Logoff sessions....*/ 
  for(i=0;i<THREADS;i++) 
  { 
    /*wait for thread to end */ 
    if (pthread_join(thread_id[i],&status)) 
      printf("Error when waiting for thread % to terminate\n", i); 
    else 
      printf("stopped\n"); 

    printf("Detach thread..."); 
    if (pthread_detach(thread_id[i])) 
      printf("Error detaching thread! \n"); 
    else 
      printf("Detached!\n"); 
    if(i==THREADS-1) 
    { 
      logoff(ctx[i]); 
      EXEC SQL CONTEXT FREE :ctx[i]; 
    } 

  } 

  if(gettimeofday(&tp2, (void*)NULL) == -1)
  {
    perror("Second: ");
    exit(0);
  }

    printf(" \n\nTHE TOTAL TIME TAKEN FOR THE PROGRAM EXECUTION = %f \n\n", (float)(tp2.tv_sec - tp1.tv_sec) + ((float)(tp2.tv_usec - tp1.tv_usec)/1000000.0));




/***********************************************************************
* Function: do_transaction 
* Description:  This functions executes SELECT 5 times and calls COMMIT. 
***********************************************************************/
void do_transaction(params) 
parameters *params; 

  struct sqlca sqlca; 
  int src_count; 
  sql_context ctx=params->ctx;                         /* 표준 프로그램에서도 대치를 해버렸네? */

  EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);                /* 함수 안에서 또 해야하는건가 보네;; */ 
  EXEC SQL CONTEXT USE :ctx; 
  printf("Thread %d executing transaction\n",params->thread_id); 
  EXEC SQL COMMIT;                                                                                                                                                 /* commit 을 이렇게;;? */
  EXEC SQL SELECT count(*) into :src_count from EMPLOYEES; 
  EXEC SQL SELECT count(*) into :src_count from EMPLOYEES; 
  EXEC SQL SELECT count(*) into :src_count from EMPLOYEES; 
  EXEC SQL SELECT count(*) into :src_count from EMPLOYEES; 
  EXEC SQL SELECT count(*) into :src_count from EMPLOYEES; 


/************************************************************** 
* Function: err_report 
* Description: This routine prints out the most recent error 
**************************************************************/ 
void      err_report(sqlca) 
struct sqlca sqlca; 

  if (sqlca.sqlcode < 0) 
    printf("\n%.*s\n\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc); 
  exit(1); 


/************************************************************ 
* Function: logon 
* Description: Logs on to the database as USERNAME/PASSWORD 
************************************************************/ 
void      logon(ctx,connect_info) 
sql_context ctx; 
char * connect_info; 

  EXEC SQL WHENEVER SQLERROR DO err_report(sqlca); 
  EXEC SQL CONTEXT USE :ctx; 
  EXEC SQL CONNECT :connect_info; 
  printf("Connected!\n"); 


/*************************************************** 
* Function: logoff 
* Description: This routine logs off the database 
***************************************************/ 
void      logoff(ctx) 
sql_context ctx; 

  EXEC SQL WHENEVER SQLERROR DO err_report(sqlca); 
  EXEC SQL CONTEXT USE :ctx;                                                 /* 현재의 context를 골라서 */
  EXEC SQL COMMIT WORK RELEASE;                                 /* commit work release 하면.. 로그오프였어... 털썩.. */
  printf("Logged off!\n"); 


퍼옴 : http://blog.naver.com/PostView.nhn?blogId=hacwatch&logNo=120150451231&parentCategoryNo=31&categoryNo=&viewDate=&isShowPopularPosts=true&from=search

반응형

'배워야 산다 > Pro-c' 카테고리의 다른 글

EXEC SQL COMMIT 및 ROLLBACK 옵션정리  (0) 2013.01.24
Thread 프로그램에서 Pro*C 구현  (0) 2013.01.24