Is multithreaded programming in pro*c supported in oracle linux version?

From: zhuchao <chao_ping_at_163.com>
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 &#26143;&#26399;&#19977; 6&#26376; 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) &params[i]))
#else

if (status = thr_create
(NULL, 0, do_transaction, &params[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

Original text of this message