GeoGeo多线程

来源:互联网 发布:ubuntu 创建文件夹 编辑:程序博客网 时间:2024/06/05 17:48

GeoGeo多线程

GeoGeo多线程有2种,1种称之为函数线程,另1中称为过程线程。

一、线程函数

普通函数中,当程序的代码调用一个函数时,程序的控制从原来的代码转移到函数中执行,函数执行完毕后,程序的控制返回给原来调用该函数的代码中,然后继续向下执行。这个过程都在一个线程内顺序发生。而多线程函数是这样一些函数,当程序的控制调用线程函数时,马上创建一个新的线程并开始运行。新线程运行的同时,原来的程序继续执行(如果以阻塞方式启动线程也可以等待线程函数结束后再向下执行)。这些新启动的线程由操作系统调度在不同的或者同一个CPU内核上运行。

线程函数是由关键字thread声明的函数,如:

thread func(double x,double y){

       …

}

调用该函数时即启动一个新的子线程。

GeoGeo在启动线程函数时,返回一个本机的线程号。这是GeoGeo给线程的编号(不是操作系统给线程的ID号),通过这个线程号,可以查询和控制线程。

如果是以阻塞方式启动的线程函数,原来调用线程函数的程序在调用时被挂起,线程结束后被唤醒,继续向下执行。非阻塞方式时,子线程启动后,调用者并不挂起和等待,而是同时执行。子线程结束时原来启动线程函数的调用者的状态和位置都是不确定的。

线程函数执行完毕后自然死亡。或者需要时,子线程函数在执行完毕之前可以被杀死。

这种由线程函数激活的子线程称之为函数线程。

二、过程

GeoGeo中一段包含执行入口的独立执行的程序称之为一个过程,其主函数(main)和其它有关函数存放在一个独立的文件中。一个过程使用TreadCall函数调用另一个过程时,GeoGeo也为其开辟一个独立的子线程运行该过程的代码,例如:

STRING str= "D:\\计时.c";

ThreadCall(str);

其中“D:\\计时.c”是D盘根目录下的一个名为“计时.c”的源代码文件。

这种由被调用过程激活的子线程称之为过程线程。

过程线程与函数线程同样有ID和运行状态。

三、线程启动与参数传递

启动线程函数和调用普通函数在形式上完全一样。调用一个线程函数会返回一个线程号,检索、查询状态等都需要使用这个线程号。启动多个线程时可以将线程号放入一个数组,以方便查询和使用。例如func是一个线程函数,循环启动时可以

int id[4];

main(){

       double a = 3.14;

       double b = 20.0;

       int i;

       for(i=0;i<4; i=i+1){

              id[i] = func(a,b,i);

       }

 }

thread func(double x,double y,int n){

}

线程函数可以任意定义函数参数,如上述for循环中循环启动的线程函数可以将循环次数i作为参数,这样子线程就知道自己是第几个子线程并且能选择处理相应的数据。

线程函数的参数不回传计算结果到调用的程序中,这一点与普通函数是不同的。

子线程与调用者的数据交换除参数传递外,还可以使用全局变量来进行。

过程线程没有参数传递,只能使用全局变量交换数据。注意启动过程的全局变量在被启动过程中是可见的。被启动过程中如果声明了与启动过程同名的全局变量,则被启动过程中的全局变量被忽略。

四、线程状态查询

一个进程/线程可以启动多个线程,每个线程有自己的ID和句柄,通过这些句柄或者线程ID可以实现线程的控制。GeoGeo给每个启动的线程一个编号,通过这个编号查询线程句柄或线程ID实现线程控制。线程编号在启动线程函数后返回,如:

int thrNo = func();

实际上在GeoGeo内,有一个内建线程列表,每个线程编号指向这个列表的一个元素。当需要检索和查询一个线程状态时,仅需要这个编号找到列表中对应的元素。

线程状态现仅设3种,活跃状态、挂起状态和死亡及线程异常。线程状态查询提供了一个查询函数ThreadStatus

int ThreadStatus(int thrNo);

函数的参数为线程编号,返回值为线程状态:0 =线程挂起,1 =线程活跃,-1 =线程死亡或异常。

五、线程挂起、唤醒和死亡

线程挂起分为自挂起和被挂起2种情况。线程自己确定需要主动等待(自挂起),或者外部进程/线程检测到某线程需要挂起等待(被挂起)。

自挂起使用下述函数:

int Suspend ();

被挂起使用函数:

int SuspendThread(int thrNo);

使用Suspend函数自挂起时无法自行唤醒自己,必须由其它进程/线程唤醒,使用自挂起的一个好处是能够确切知道线程的挂起点,以便线程恢复时准确继续执行。使用SuspendThread函数挂起其它线程无法确切指定被挂起线程的挂起点。

一个线程无论自己挂起还是被其它进程/线程挂起都不能自行恢复,因为挂起是线程自己处于一种僵死状态,必须由其它进程/线程唤醒。唤醒线程使用下述函数:

int ResumeThread(int thrNo);

一个线程函数执行完毕后可能会自然结束,还有一种方法可以强行结束线程,即使用KillThread函数马上杀死一个线程。

int KillThread(int thrNo);

尽量避免使用KillThread函数,最好让线程函数自然死亡。

六、线程同步与数据锁

对资源的访问控制是线程同步的重要内容,GeoGeo也设计了自己的同步机制。此外还设计了数据集的锁定功能。

GeoGeo的每个数据集都是一个对象,不但有数据本身,还有描述该数据的一些辅助信息和部分存取代码。这样做的优点是可以方便对数据进行查询,可以设定数据的状态以及其它一些对数据的控制。例如可以设定数据锁定的状态并向被授权的线程分发访问许可,以便允许其它线程的进行访问。

存取锁定的数据集需要使用该锁的钥匙。锁定该数据集的线程拥有该锁的钥匙。数据锁的钥匙可以在授权的线程中传递。

有关更多的GeoGeo多线程方面内容请参阅《GEOGEO-PART1GeoGeo脚本基础第5章。

示例程序清单中5-1~5-13提供了有关多线程的示例代码以供参考。

 

 

下载地址:http://download.csdn.net/detail/gordon3000/7922555 

0 0