欢迎来到天天文库
浏览记录
ID:42465660
大小:81.50 KB
页数:7页
时间:2019-09-15
《VC线程同步技术剖析1》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、VC线程同步技术剖析12009-02-1009:45VC线程同步技术剖析12008年04月17日星期四15:30在程序中使用多线程时,一般很少冇多个线程能在其生命期内进行完全独立的操作。更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解。正常情况下对这种处理结果的了解应当在其处理任务完成后进行。如果不釆取适当的措施,其他线程往往会在线程处理任务结束前就去访问处理结果,这就很冇可能得到冇关处理结果的错误了解。例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题。如果一个线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证
2、读取到的数据是经过写线程修改后的。为了确保读线程读取到的是经过修改的变量,就必须在向变量写入数据时禁止其他线程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。象这种保证线程能了解其他线程任务处理结束后的处理结果而采取的保护措施即为线程同步。线程同步是一个非常大的话题,包括方方面面的内容。从大的方面讲,线程的同步可分用户模式的线程同步和内核对象的线程同步两大类。用户模式中线程的同步方法主要冇原子访问和临界区等方法。其特点是同步速度特别快,适合于对线程运行速度冇严格耍求的场合。内核对象的线程同步则主要山事件、等待定时器、信号量以及信号灯等内核对象构成。山于这种同步
3、机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,而这种转换一般要耗费近千个CPU周期,因此同步速度较慢,但在适用性上却要远优于用户模式的线程同步方式。临界区临界区(CriticalSection)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所冇试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用E
4、ntcrCriticalSection()和LeavoCriticalScction()函数去标识和释放一个临界区。所用到的CRITICALSECTTON结构对象必须经itInitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之卞。否则临界区将不会起到应有的作用,共亨资源依然有被破坏的可能。onclickz,javascript:window,open(this,sre)onload=z,javascript:if(this.width>500){this.resized=true;
5、this,style.width=500;}"border二0>图1使用临界区保持线程同步下面通过一段代码展示了临界区在保护多线程访问的共享资源中的作用。通过两个线程来分别对全局变量g_cArray[10]进行写入操作,用临界区结构对象£_cs来保持线程的同步,并在开启线程前对其进行初始化。为了使实验效果更加明显,体现出临界区的作用,在线程函数对共享资源g_cArray[10]的写入时,以Sleep()函数延迟1毫秒,使其他线程同其抢占CPU的可能性增大。如果不使用临界区对其进行保护,则共亨资源数据将被破坏(参见图1(a)所示计算结果),而使用临界区对线程保持同步后则可以得
6、到止确的结果(参见图1(b)所示计算结果)。代码实现清单附下://临界区结构对象CRITICAL_SECTIONg_cs;//共亨资源charg_cArray[10];U1NTThreadProc10(LPV01DpParam){//进入临界区EnterCriticalSection(&g_cs);//对共享资源进行写入操作for(inti=0;i<10;i++){g_cArray[i]二'a';Slcep(l);}//离开临界区LeaveCriticalSection(&gcs);return0;}UINTThreadProc11(LPVOIDpParam){//进入临界
7、区EnterCriticalSection(&g_cs);//对共享资源进行写入操作for(inti=0;i<10;i++){g_cArray[10-i-1]二'b';Sleep(l);}//离开临界区LeaveCriticalSection(&gcs);return0;voidCSampleO8View::0nCriticalSection()//初始化临界区InitializeCriticalSection(&gcs);//启动线程xBcginThread(ThreadProc10,NULL);AfxBcgin
此文档下载收益归作者所有