OCI提供了一个统一的线程调用接口,使OCI程序能够进行线程编程,不过这个接口也是有限制的,如果OCI程序运行的操作系统不支持多线程,调用接口就会出错。
要想使用OCI的多线程接口,也是有调用顺序的,OCI的文档只提供了一堆函数,并没有给出函数调用的步骤,在这里我们看一下具体的操作。主调用线程的步骤。
1. 创建一个OCI环境句柄,必须使用OCI_THREADED模式,否则会出现信号11引起的段错误。
2. 线程包在进程级别的初始化操作,调用OCIThreadProcessInit()函数。
3. 初始化线程包的上下文信息,调用OCIThreadInit()函数。
4. 为每个要创建的线程初始化线程ID,调用OCIThreadIdInit()函数。
5. 为每个要创建的线程初始化线程句柄,调用OCIThreadHndInit()函数。
6. 创建每一个线程,调用OCIThreadCreate()函数。
7. 子线程分别开始执行,主线程调用OCIThreadJoin()函数,等待每个子线程结束。
8. 主线程关闭每个子线程句柄,调用OCIThreadClose()函数。
9. 主线程销毁每个子线程的ID和句柄,调用OCIThreadIdDestroy()和OCIThreadHndDestroy()函数。
10. 主线程结束线程包上下文,调用OCIThreadTerm()函数。
先来看看各个函数的原型和参数。
初始化线程包函数OCIThreadProcessInit(),原型和参数如下。
void OCIThreadProcessInit ( );
这个函数比较简洁,没有参数,也没有返回值。
初始化线程包的上下文函数OCIThreadInit(),原型和参数如下。
sword OCIThreadInit ( void *hndl, OCIError *err );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
初始化线程ID函数OCIThreadIdInit(),原型和参数如下。
sword OCIThreadIdInit ( void *hndl,
OCIError *err,
OCIThreadId **tid );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
tid是一个输出参数,是一个指针的指针,指向要初始化的线程ID。
初始化线程句柄函数OCIThreadHndInit(),原型和参数如下。
sword OCIThreadHndInit ( void *hndl,
OCIError *err,
OCIThreadHandle **thnd );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
thnd是一个输出参数,是一个指针的指针,指向要初始化的线程句柄。
创建线程函数OCIThreadCreate(),原型和参数如下。
sword OCIThreadCreate ( void *hndl,
OCIError *err,
void (*start) (void *),
void *arg,
OCIThreadId *tid,
OCIThreadHandle *tHnd );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
start是一个输入参数,线程函数指针,新线程的入口函数。
arg是一个输入参数,传递给线程函数的参数。
tid是一个输入/输出参数,返回线程的ID。
tHnd是一个输入/输出参数,返回线程的句柄。
线程加入函数OCIThreadJoin(),原型和参数如下。
sword OCIThreadJoin ( void *hndl,
OCIError *err,
OCIThreadHandle *tHnd );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
tHnd是一个输入参数,要加入的线程的句柄。
这个函数不太好理解,其实说白了,就是程序执行到这个函数时,加入tHnd线程的代码,要等到线程代码执行完了,才能执行函数后面的程序代码,好比是把线程代码放到了这个函数之前先执行。
关闭线程句柄函数OCIThreadClose(),原型和参数如下。
sword OCIThreadClose ( void *hndl,
OCIError *err,
OCIThreadHandle *tHnd );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
tHnd是一个输入参数,要关闭的线程的句柄。
这个函数与OCIThreadHndInit()函数是相对的,关闭初始化并且创建后返回的线程句柄。
销毁线程ID函数OCIThreadIdDestroy(),原型和参数如下。
sword OCIThreadIdDestroy (void *hndl,
OCIError *err,
OCIThreadId **tid );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
tid是一个输入/输出参数,指向被销毁的线程ID。
销毁线程句柄函数OCIThreadHndDestroy(),原型和参数如下。
sword OCIThreadHndDestroy ( void *hndl,
OCIError *err,
OCIThreadHandle **thnd );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
thnd是一个输入/输出参数,指向被销毁的线程句柄。
结束线程包上下文函数OCIThreadTerm(),原型和参数如下。
sword OCIThreadTerm ( void *hndl, OCIError *err );
hndl是一个输入/输出参数,OCI的环境句柄。
err是一个输入/输出参数,错误句柄,返回错误码和错误信息文本。
这个函数与OCIThreadInit()相对应,每调用一次初始化,都要相应的结束一次。
下一节我们写一个代码实例演示一下线程函数的使用过程。