Informix支持一个进程中的多个线程同时对数据库进行操作,既可以多个线程使用多个数据库连接,也可以多个线程共享一个数据库连接。无论是那种方式,都需要认真分析处理多线程的共享变量之间加锁、解锁的处理。
本文针对多线程的EC程序中的几个问题进行说明:
1、编译连接
当只有一个完整的ec文件时,可以使用ESQL的-thread选项,ESQL会自动编译连接线程安全的informix库。
当存在多个文件,包括ec、c、C文件时,可以首先使用ESQL的-c和-thread选项将ec文件编译成.o文件,然后使用连接器强制连接线程安全的库(th库)。
总之要求下面几点:
A、配置环境变量THREADLIB=POSIX
B、ESQL要加上-thread选项
C、保证连接的是线程安全的库。
2、多个线程共享一个连接
多个线程共享一个连接时,在连接建立好以后,可以在一个线程中使用
EXEC SQL set connection 'con1' dormant;
将连接置于dormant状态,此时的连接可以被其它的线程激活。
其它线程使用
do {
EXEC SQL set connection 'con1';
} while ( ( sqlca.sqlcode == -1802 ) );
将连接激活,此时可以访问数据库了,而且只用本线程可以访问数据库。只有本线程将连接置为dormant后,才可以再被其它的线程使用。
3、多个线程使用多个连接
A、此时每个线程需要有自己的连接名,各个连接名必须不同。
B、必须仔细处理共享变量的互斥访问。
EXEC SQL connect to connection 'db1' as 'con1';
EXEC SQL connect to connection 'db1' as 'con2';
其中'db1'是数据库名,'con1'是连接名
4、连接用完之后使用disconnect 断开连接
EXEC SQL disconnect 'con1';
或者
EXEC SQL disconnect all;
多个线程共享一个连接的例子:
create table zy(
id integer,
nam varchar(60,0)
)
#define _H_LOCALEDEF
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
EXEC SQL INCLUDE SQLCA;
void* thread1(void* arg)
{
do {
EXEC SQL set connection 'con1';
} while (SQLCODE== -1802);
EXEC SQL BEGIN WORK;
EXEC SQL insert into zy values (1,'mm'); /* table t2 is in db1 */
EXEC SQL COMMIT WORK;
EXEC SQL set connection 'con1' dormant;
}
void* thread2(void* arg)
{
do {
EXEC SQL set connection 'con1';
} while (SQLCODE== -1802);
EXEC SQL BEGIN WORK;
EXEC SQL insert into zy values (2,'yy'); /* table t2 is in db1 */
EXEC SQL COMMIT WORK;
EXEC SQL set connection 'con1' dormant;
}
int main(int argc, char *argv[])
{
pthread_t tid[8];
int arg[8];
int ret=0;
void* res;
EXEC SQL connect to 'db1' as 'con1';
EXEC SQL set connection 'con1' dormant;
ret = pthread_create(&tid[0],NULL, thread1, (void*)&arg[0]);
if(ret!=0){
printf("%s,[%d] create thread error[%d]!\n",__FILE__,__LINE__,ret);
exit(1);
}
ret = pthread_create(&tid[1],NULL, thread2, (void*)&arg[1]);
if(ret!=0){
printf("%s,[%d] create thread error[%d]!\n",__FILE__,__LINE__,ret);
exit(1);
}
ret = pthread_join(tid[0], &res);
if(ret != 0){
printf("%s,[%d] can’t join thread[%s]!\n",__FILE__,__LINE__,strerror(ret));
exit(1);
}
ret = pthread_join(tid[1], &res);
if(ret != 0){
printf("%s,[%d] can’t join thread[%s]!\n",__FILE__,__LINE__,strerror(ret));
exit(1);
}
EXEC SQL set connection 'con1';
EXEC SQL disconnect 'con1';
return 0;
}
多个线程使用多个连接的例子:
create table zy(
id integer,
nam varchar(60,0)
)
#define _H_LOCALEDEF
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
EXEC SQL INCLUDE SQLCA;
void* thread1(void* arg)
{
EXEC SQL connect to 'db1' as 'con1';
EXEC SQL BEGIN WORK;
EXEC SQL insert into zy values (1,'mm'); /* table t2 is in db1 */
EXEC SQL COMMIT WORK;
EXEC SQL disconnect 'con1';
}
void* thread2(void* arg)
{
EXEC SQL connect to 'db1' as 'con2';
EXEC SQL BEGIN WORK;
EXEC SQL insert into zy values (2,'yy'); /* table t2 is in db1 */
EXEC SQL COMMIT WORK;
EXEC SQL disconnect 'con2';
}
int main(int argc, char *argv[])
{
pthread_t tid[8];
int arg[8];
int ret=0;
void* res;
ret = pthread_create(&tid[0],NULL, thread1, (void*)&arg[0]);
if(ret!=0){
printf("%s,[%d] create thread error[%d]!\n",__FILE__,__LINE__,ret);
exit(1);
}
ret = pthread_create(&tid[1],NULL, thread2, (void*)&arg[1]);
if(ret!=0){
printf("%s,[%d] create thread error[%d]!\n",__FILE__,__LINE__,ret);
exit(1);
}
ret = pthread_join(tid[0], &res);
if(ret != 0){
printf("%s,[%d] can’t join thread[%s]!\n",__FILE__,__LINE__,strerror(ret));
exit(1);
}
ret = pthread_join(tid[1], &res);
if(ret != 0){
printf("%s,[%d] can’t join thread[%s]!\n",__FILE__,__LINE__,strerror(ret));
exit(1);
}
return 0;
}