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");
}
* 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 |