Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 (Deutsch) » SQL Anywhere Server - Programmierung » Embedded SQL » SQL-Kommunikationsbereich (SQLCA)

 

SQLCA-Verwaltung für Code mit mehreren Threads oder "reentrant"-Code

Sie können Embedded SQL-Anweisungen in Code mit mehreren Threads oder in reentrant-Code verwenden. Wenn Sie allerdings eine einfache Verbindung verwenden, sind Sie auf eine aktive Anforderung pro Verbindung beschränkt. Vermeiden Sie bei einer Anwendung mit mehreren Threads, für alle Threads dieselbe Verbindung zur Datenbank zu verwenden, ausgenommen, Sie verwenden Semaphore für die Zugriffssteuerung.

Sie können ohne Einschränkung für jeden Thread, der die Datenbank nutzen will, eine separate Verbindung öffnen. Der SQLCA-Bereich wird von der Laufzeitbibliothek benutzt, um zwischen den verschiedenen Thread-Kontexten zu unterscheiden. Daher braucht jeder Thread, der eine Verbindung zur Datenbank benötigt, seinen eigenen SQCLA-Bereich. Die Ausnahme ist, dass ein Thread die Funktion db_cancel_request verwenden kann, um eine Anweisung abzubrechen, die unter Verwendung des SQLCA dieses Threads auf einem anderen Thread ausgeführt wird.

Das folgende Beispiel enthält Embedded SQL-Reentrant-Code mit mehreren Threads.



#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <stdlib.h>
#include <process.h>
#include <windows.h>
EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;

#define TRUE 1
#define FALSE 0

// multithreading support

typedef struct a_thread_data {
    SQLCA sqlca;
    int num_iters;
    int thread;
    int done;
} a_thread_data;

// each thread's ESQL test

EXEC SQL SET SQLCA "&thread_data->sqlca";

static void PrintSQLError( a_thread_data * thread_data )
/******************************************************/
{
  char                buffer[200];

  printf( "%d: SQL error %d -- %s ... aborting\n",
      thread_data->thread,
      SQLCODE,
      sqlerror_message( &thread_data->sqlca, 
               buffer, sizeof( buffer ) ) );
    exit( 1 );
}

EXEC SQL WHENEVER SQLERROR { PrintSQLError( thread_data ); };

static void do_one_iter( void * data )
{
  a_thread_data *  thread_data = (a_thread_data *)data;
  int    i;
  EXEC SQL BEGIN DECLARE SECTION;
  char    user[ 20 ];
  EXEC SQL END DECLARE SECTION;

  if( db_init( &thread_data->sqlca ) != 0 ) {
    for( i = 0; i < thread_data->num_iters; i++ ) {
     EXEC SQL CONNECT "dba" IDENTIFIED BY "sql";
     EXEC SQL SELECT USER INTO :user;
     EXEC SQL DISCONNECT;
    }
    printf( "Thread %d did %d iters successfully\n",
        thread_data->thread, thread_data->num_iters );
    db_fini( &thread_data->sqlca );
  }
  thread_data->done = TRUE;
}

int main() 
{
  int num_threads = 4;
  int thread;
  int num_iters = 300;
  int num_done = 0;
  a_thread_data *thread_data;
  thread_data = (a_thread_data *)malloc( sizeof(a_thread_data) * num_threads );
  for( thread = 0; thread < num_threads; thread++ ) {
    thread_data[ thread ].num_iters = num_iters;
    thread_data[ thread ].thread = thread;
    thread_data[ thread ].done = FALSE;
    if( _beginthread( do_one_iter, 
      8096, 
      (void *)&thread_data[thread] ) <= 0 ) {
      printf( "FAILED creating thread.\n" );
      return( 1 );
    }
  }
    while( num_done != num_threads ) {
    Sleep( 1000 );
    num_done = 0;
    for( thread = 0; thread < num_threads; thread++ ) {
      if( thread_data[ thread ].done == TRUE ) {
        num_done++;
      }
    }
  }
  return( 0 );
}
 Siehe auch