Sie können Embedded SQL-Anweisungen in Code mit mehreren Threads oder reentrant-Code verwenden. Wenn Sie allerdings eine einfache Verbindung verwenden, sind Sie auf eine aktive Anforderung pro Verbindung beschränkt. In einer Anwendung mit mehreren Threads sollten Sie es vermeiden, 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.
Jede einzelne Datenbankverbindung ist nur von einem einzelnen SQLCA-Bereich aus zugänglich, außer bei der Abbruchanweisung, die von einem separaten Thread aus ausgegeben werden muss.
Hinweise zur Abbruchanforderung finden Sie unter Anforderungsverwaltung implementieren.
Das folgende Beispiel enthält reentrant Embedded SQL-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 ); } |
Kommentieren Sie diese Seite in DocCommentXchange. Senden Sie uns Feedback über diese Seite via E-Mail. |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |