Is multithreaded programming in pro*c supported in oracle linux version?
Date: 25 Jun 2002 23:53:13 -0700
Message-ID: <d8e45edf.0206252253.54206570_at_posting.google.com>
/home/oracle/product/8.1.7/bin/proc threads=yes parse=none code=ansi_c iname=mltthread.pc SQLCHECK=FULL USERID=scott/tiger_at_EACHNET
Pro*C/C++: Release 8.1.7.0.0 - Production on 星期三 6月 26 14:50:45 2002
(c) Copyright 2000 Oracle Corporation. All rights reserved.
System default option values taken from: /home/oracle/product/8.1.7/precomp/admin/pcscfg.cfg
Semantic error at line 106, column 19, file mltthread.pc:
sql_context ctx[THREADS]; ..................1
PCC-S-02322, found undefined identifier
Semantic error at line 106, column 19, file mltthread.pc:
sql_context ctx[THREADS]; ..................1
PCC-S-02322, found undefined identifier
make: *** [mltthrd] Error 1
//////////////////////////////////////////The program body is like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
//EXEC SQL INCLUDE SQLCA;
#define _EXC_OS_ _EXC__UNIX
#define _CMA_OS_ _CMA__UNIX
#ifdef DCE_THREADS
#include <pthread.h>
#else
#include <thread.h>
#endif
/* Function prototypes */
void err_report();
#ifdef DCE_THREADS
void do_transaction();
#else
void *do_transaction();
#endif
void get_transaction();
void logon();
void logoff();
#define CONNINFO "scott/tiger_at_eachnet"
#define THREADS 3
EXEC SQL BEGIN DECLARE SECTION;
struct parameters
{ sql_context * ctx;
int thread_id;
};
typedef struct parameters parameters;
struct record_log
{ char action;
unsigned int from_account;
unsigned int to_account;
float amount;
};
typedef struct record_log record_log;
EXEC SQL END DECLARE SECTION; record_log records[]= { { 'M', 10001, 10002, 12.50 },
{ 'M', 10001, 10003, 25.00 }, { 'M', 10001, 10003, 123.00 }, { 'M', 10001, 10003, 125.00 }, { 'M', 10002, 10006, 12.23 }, { 'M', 10007, 10008, 225.23 }, { 'M', 10002, 10008, 0.70 }, { 'M', 10001, 10003, 11.30 }, { 'M', 10003, 10002, 47.50 }, { 'M', 10002, 10006, 125.00 }, { 'M', 10007, 10008, 225.00 }, { 'M', 10002, 10008, 0.70 }, { 'M', 10001, 10003, 11.00 }, { 'M', 10003, 10002, 47.50 }, { 'M', 10002, 10006, 125.00 }, { 'M', 10007, 10008, 225.00 }, { 'M', 10002, 10008, 0.70 }, { 'M', 10001, 10003, 11.00 }, { 'M', 10003, 10002, 47.50 }, { 'M', 10008, 10001, 1034.54}};
static unsigned int trx_nr=0;
#ifdef DCE_THREADS
pthread_mutex_t mutex;
#else
mutex_t mutex;
#endif
/********************************************************************** Main
********************************************************************/main()
{
EXEC SQL BEGIN DECLARE SECTION; sql_context ctx[THREADS]; EXEC SQL END DECLARE SECTION;
#ifdef DCE_THREADS
pthread_t thread_id[THREADS];
pthread_addr_t status;
#else
thread_t thread_id[THREADS];
int status;
#endif
parameters params[THREADS];
int i;
EXEC SQL ENABLE THREADS;
EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
/* 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);
}
/*Create mutex for transaction retrieval */
#ifdef DCE_THREADS
if (pthread_mutex_init(&mutex,pthread_mutexattr_default))
#else
if (mutex_init(&mutex, USYNC_THREAD, NULL))
#endif
{
printf("Can't initialize mutex\n");
exit(1);
}
/*Spawn threads*/
for(i=0;i<THREADS;i++)
{
params[i].ctx=ctx[i];
params[i].thread_id=i;
printf("Thread %d... ",i);
#ifdef DCE_THREADS
if (pthread_create(&thread_id[i],pthread_attr_default,
(pthread_startroutine_t)do_transaction,
(pthread_addr_t) ¶ms[i]))
#else
if (status = thr_create
(NULL, 0, do_transaction, ¶ms[i], 0, &thread_id[i]))
#endif
printf("Cant create thread %d\n",i);
else
printf("Created\n");
}
/* Logoff sessions....*/
for(i=0;i<THREADS;i++)
{
/*wait for thread to end */
printf("Thread %d ....",i);
#ifdef DCE_THREADS
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");
#else
if (thr_join(thread_id[i], NULL, NULL))
printf("Error waiting for thread to terminate\n");
#endif
printf("Stop Session %d....",i);
logoff(ctx[i]);
EXEC SQL CONTEXT FREE :ctx[i];
}
/*Destroys mutex*/
#ifdef DCE_THREADS
if (pthread_mutex_destroy(&mutex))
#else
if (mutex_destroy(&mutex))
#endif
{
printf("Can't destroy mutex\n");
exit(1);
}
}
/********************************************************************* * Function: do_transaction * * Description: This functions executes one transaction out of the * records array. The records array is 'managed' by * the get_transaction function. *
*
********************************************************************/
#ifdef DCE_THREADS
void do_transaction(params)
#else
void *do_transaction(params)
#endif
parameters *params;
{
struct sqlca sqlca;
EXEC SQL BEGIN DECLARE SECTION;
record_log * trx;
EXEC SQL END DECLARE SECTION;
sql_context ctx=params->ctx;
/* Done all transactions ? */
while (trx_nr < (sizeof(records)/sizeof(record_log)))
{
get_transaction(&trx);
EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
EXEC SQL CONTEXT USE :ctx;
printf("Thread %d executing transaction\n",params->thread_id);
switch(trx->action)
{
case 'M': EXEC SQL UPDATE ACCOUNTS
SET BALANCE=BALANCE+:trx->amount
WHERE ACCOUNT=:trx->to_account;
EXEC SQL UPDATE ACCOUNTS
SET BALANCE=BALANCE-:trx->amount
WHERE ACCOUNT=:trx->from_account;
break;
default: break;
}
EXEC SQL COMMIT;
}
}
/***************************************************************** * 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 BEGIN DECLARE SECTION;
char * conn=connect_info;
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER SQLERROR DO err_report(sqlca);
EXEC SQL CONTEXT USE :ctx;
EXEC SQL CONNECT :conn;
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;
EXEC SQL COMMIT WORK RELEASE;
printf("Logged off!\n");
}
/****************************************************************** * Function: get_transaction * * Description: This routine returns the next transaction to process*
******************************************************************/void get_transaction(trx)
record_log ** trx;
{
#ifdef DCE_THREADS
if (pthread_mutex_lock(&mutex))
#else
if (mutex_lock(&mutex))
#endif
printf("Can't lock mutex\n");
*trx=&records[trx_nr];
trx_nr++;
#ifdef DCE_THREADS
if (pthread_mutex_unlock(&mutex))
#else
if (mutex_unlock(&mutex))
#endif
printf("Can't unlock mutex\n");
}
Received on Wed Jun 26 2002 - 08:53:13 CEST