WIN32多线程程序设计学习笔记(第三章)

原创 2007年09月17日 20:05:00
通过在上一章的学习,我学会使用GetExitCodeThread()这个函数来判断一个线程是否还在执行。通过这个函数,我就可以对付“某个线程必须在某个线程结束后才能运行”的情况。复习一下:
程序片段:
              for ( ; ; )
              {
                     int rc;
                     rc = GetExitCodeThread(hThrd,&exitCode);
                     if (!rc && exitCode != STILL_ACTIVE)
                            break;
              }
使用这个方法,必须持续不断的调用GetExitCodeThread(),直到其结果不再是STILL_ACTIVE。书上说这方法不好,很浪费cpu时间.,称为忙等待(busy waits)。忙等待cpu几乎用了所有的可用时间去检查线程是否结束。必须应有的重视,不然你会发现当包含忙等待的程序运行起来后,其它正在进行的程序的反应就很迟钝了。因为
 
那么,我应该怎么做呢?如何才更有效率呢?
 
另一种有效率的方法:
使用WaitForSingleObject()这个函数来完美的解决问题。
完成上面程序片段同样功能只需一句话:
WaitForSingleObject ( hThrd, INFINITE );
hThrd线程没有结束时,调用这个函数的程序就会在函数调用点停下来,直到hThrd线程结束时(术语:hThrd被激发)才继续向下执行。
不知道大家会不会有这样疑问------这个函数不会只是把上面的程序片段包装了一下吧?它真是很有效率吗?如果它有效率,它是如何做到的呢?
可以告诉大家,WaitForSingleObject()不是上述程序片段的简单包装,它真的很有效率(不信,按书上的方法,打开性能管理器看看),至于它如何做到的,我也有兴趣知道(知道告诉我),我只知道这个函数得到了操作系统级的某些底层调度函数的支持。
 
基本上本章的核心内容就是以上所述了。(至于WaitForSingleObject()参数及返回值的说明,查书就行了,毋需多言)
 
 
具体的看一个实在的例子,胜过在此长篇大论,下面请看:
//参考书上例子
//程序的目的:只用3个线程,完成6件事
int main()
{
              HANDLE        hThrds[3];
 
              int slot = 0;
              For ( int I=1 ; I<=6 ; I++)
              {
                     if( I > 3 )
                     {//已经存在3个线程了
//等待其中的一个线程线束后,再创建线程做剩余的事情
//效率不高,因为线程结束的次序与它们被产生的次序不同
WaitForSingleObject( hThrds[slot] , INFINITE ) ;
CloseHandle ( hThrds[slot] );
                     }
 
                     //构造线程
                     hThrds[slot] = CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);
                    
                     if (++slot>2)
                            slot=0;
}// end for
 
for ( slot=0; slot<3; slot++)
{
       //等待剩余的线程结束
       WaitForSingleObject( hThrds[slot] , INFINITE ) ;
       CloseHandle ( hThrds[slot] );
}// end for
}
 
上面的这段程序有一个问题,就是效率不是很高;理想的状况是,一旦有一个线程结束,就立刻产生一个线程补上。仔细读上面的程序,你会发现它无法实现理想的状况;因为它假设线程结束的次序会和它们被产生的次序相同。比如,当依序产生了1,2,3线程以后,一定是按1,2,3的次序结束。其实不然,也许2比1更早结束。在这时,上面的程序并不会立刻产生一个线程填补2,而是非要等1结束了,才产生线程。那么能够实现理想的状况吗?答案是可以,请用WaitForMultipleObjects() 函数, 这个函数的用法基本上与WaitForSingleObject()差不多,在这里我就不举例说明了。
 
本章最后还提到了MsgWaitForMultipleObjects() , 这个函数特点是在消息到达或线程结束时返回。
 
我想,只要用会了WaitForSingleObject()这个函数, 那么WaitForMultipleObjects()MsgWaitForMultipleObjects()看一下也就会用了(书上举了两个小例子来说明,看一下花不了多少时间,不必我在这里废话了)。
 
这一章节的内容大概就是这么多,总结一下:
* 等待线程结束                  [ WaitForSingleObject()         ]
* 等待多个线程结束              [ WaitForMultipleObjects()               ]
* 等待多个线程结束或消息到达    [ MsgWaitForMultipleObjects()        ]
 
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《win32多线程程序设计》学习笔记二

一、产生一个线程 1、产生一个线程(并因而成就一个多线程程序),是以CreateThread()函数作为开始。此函数原型如下: 二、使用多线程的结果 1、多线程程序无法预...

《win32多线程程序设计》学习笔记五

一、干净的终止一个线程 1、利用TerminateThread()放弃一个线程  注:尽量不要使用TerminateThread()函数。 2、几个可能的终止一个线程的方法  1)、使用信...

《win32多线程程序设计》学习笔记四

一、Critical Sections

转载:《Win32多线程程序设计》学习笔记 第10章 MFC 中的线程

《Win32多线程程序设计》学习笔记 第10章 MFC 中的线程 如果要在MFC程序中产生一个线程,而该线程将调用MFC函数或者使用MFC的任何数据,那么你必须以AfxBeginThre...

《Win32多线程程序设计》读书笔记(一)

1,可以使用GetExitThreadCode函数获取线程函数结束时的返回值 2,多线程程序设计成功的关键: 2.1,各线程的数据要分离开来,避免使用全局变量 2.2,不要在线程之间共享GDI对象 2...

《Win32多线程程序设计》读书笔记之内核对象

所谓句柄(Handle),其实就是指针,指向操作系统内存空间中的某样东西,为了维护系统的完整性与安全性,不允许直接取得。 内核对象与GDI对象不同,内核对象由KERNEL32.DLL管理,而GD...

win 32多线程程序设计读书笔记

一直不是很熟悉windows下的编程,借着学习侯捷老师翻译的《win32 多线程程序设计》来完成操作系统的作业。 1.今天学到的比较重要的概念是核心对象(一下大部分话出自该书): 核心对象可以有...

《Win32多线程程序设计》(3)---同步控制

让我先对同步(synchronous)与异步(asynchronous)做个说明。当程序1调 用程序2时,程序1停下不动,直到程序2完成回到程序1来,程序1才继 续下去,这就是所谓的“synchron...

《Win32多线程程序设计》(14)---操作I/O Completion Port

操作概观 1. 产生一个 I/O completion port。 2. 让它和一个文件handle 产生关联。 3. 产生一堆线程。 4. 让每一个线程都在com pletion port 上等待。...

深入浅出Win32多线程程序设计之二:线程控制

深入浅出Win32多线程程序设计之线程控制   WIN32线程控制主要实现线程的创建、终止、挂起和恢复等操作,这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数。  1.线程函...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)