wince驱动开发四

 7. TryEnterCriticalSection和EnterCriticalSection的差别是什么?

如果EnterCriticalSection将一个线程置于等待状态,那么该线程在很长时间内就不能再次被调度。实际上,在编写得不好的应用程序中,该线程永远不会再次被赋予CPU时间。TryEnterCriticalSection函数决不允许调用线程进入等待状态。它的返回值能够指明调用线程是否能够获得对资源的访问权。TryEnterCriticalSection发现该资源已经被另一个线程访问,它就返回FALSE。在其他所有情况下,它均返回TRUE。运用这个函数,线程能够迅速查看它是否可以访问某个共享资源,如果不能访问,那么它可以继续执行某些其他操作,而不必进行等待。如果TryEnterCriticalSection函数确实返回了TRUE,那么CRITICAL_SECTION的成员变量已经更新。

8. BIB 文件格式
ROMIMAGE 使用二进制映像生成器 (BIB) 文件来对它应当如何配置 ROM 进行配置。BIB 文件只是以关键字定义四个不同节的纯文本文件。
模块节以在独立的一行上的关键字 MODULES 进行标识。在模块节中,列出了将要就地执行 (XIP) 的代码的可执行文件模块。文件节(关键字 FILES)列出了要放在映像中的其他文件(位图、数据文件、HTML 页等等)。它还可以指定不是专门用于 XIP 的可执行文件模块。很少使用的诊断应用程序很适合被指定在这里。默认情况下,文件节中的项目经过了压缩,以减小大小。
模块和文件节的条目的语法非常简单:
<Target Name> <Whitespace> <Workstation path> <memory Section> <flags>
<目标名>是出现在 ROM 中的该文件的名称。<工作站路径>是 ROMIMAGE 将用来查找实际文件的路径(通常基于 $(_FLATRELEASEDIR))。内存节将是几乎没有例外的“NK”。(启动加载程序是一个常见的例外)。
下表总结了这些标志:
标志   用途    
C   压缩(默认用于文件节)    
U   未压缩(默认用于模块节)    
R   只压缩资源    
H   隐藏文件    
S   系统文件  

 

 

 

9、线程优先级:
  线程除了能够访问进程的资源外,每个线程还拥有自己的栈。栈的大小是可以调整的,最小为1KB或4KB(也就是一个内存页。内存页的大小取决于CPU),一般默认为64KB,但栈顶端永远保留2KB为防止溢出。如果要改变栈初始时大小,在EVC"Project"-"Settings"-"Link"链接选项"/STACK"后的参数中指定大小。其中参数1为默认大小,参数2为一个内存页大小,都用十六进制表示。如果将栈的初始值设置太小,很容易导致系统访问非法并立即终止进程。使用UserKInfo[KINX_PAGESIZE]来获得系统页大小。
  线程有五中状态,分别为运行、挂起、睡眠、阻塞、终止。当所有线程全部处于阻塞状态时,内核处于空闲模式(Idle mode),这时对CPU的电力供应将减小。
创建一个线程的API函数如下:

HANDLE  CreateThread(LPSECURITY_ATTRIBUTES  lpThreadAttributes,

               DWORD  dwStackSize,

               LPTHREAD_START_ROUTINE  lpStartAddress,

               LPVOID  lpParameter,

               DWORD  dwCreationFlags, 

               LPDWORD  lpThreadId );      

Windows CE.NET 不支持安全性所以参数1必须设置为0。如果参数5为STACK_SIZE_PARAM_IS_A_RESERVATION,那么参数2可以指定栈的大小,内核将按照参数2的数值来为此线程拥有的栈保留地址空间。如果参数5不为STACK_SIZE_PARAM_IS_A_RESERVATION,那么参数2必须设置为0。参数3为执行路径的首地址,也就是函数的地址。参数4用来向线程中传递一个参数。参数5除了上面说明外,还可以为0、CREATE_SUSPENDED。CREATE_SUSPENDED表示这个线程在创建后一直处于挂起状态,直到用ResumeThread函数来恢复。最后一个参数保存函数返回的创建的线程ID。
  退出一个线程同退出一个进程有类似的方法。最好是由函数返回,在线程中调用ExitThead函数也可以

。在当前线程中终止另一个线程使用TerminateThread函数。此函数在使一个线程退出时,会通知这个线

程加载的所有DLL。这样DLL就可以做结束工作了。
  Windows CE.NET不像其他Windows操作系统将进程分为不同的优先级类,Windows CE.NET只将线程分

为256个优先级。0优先级最高,255最低,0到248优先级属于实时性优先级。0到247优先级一般分配给实

时性应用程序、驱动程序、系统程序。249到255优先级中,251优先级(THREAD_PRIORITY_NORMAL)是正

常优先级。255优先级(THREAD_PRIORITY_IDLE)为空闲优先级。249优先级(THREAD_PRIORITY_HIGHEST

)是高优先级。248到255优先级一般分配给普通应用程序线程使用。具体分段见下表:
 
优先级范围 分配对象
0-96 高于驱动程序的程序
97-152 基于Windows CE的驱动程序
153-247 低于驱动程序的程序
248-255 普通的应用程序
  Windows CE.NET操作系统具有实时性,所以调度系统必须保证高优先级线程先运行,低优先级线程在

高优先级线程终止后或者阻塞时才能得到CPU时间片。而且一旦发生中断,内核会暂停低优先级线程的运

行,让高优先级线程继续运行,直到终止或者阻塞。具有相同优先级的线程平均占有CPU时间片,当一个

线程使用完了CPU时间片或在时间片内阻塞、睡眠,那么其他相同优先级的线程会占有时间片。这里提到

的CPU时间片是指内核限制线程占有CPU的时间,默认为100ms。OEM可以更改这个值,甚至设置为0。如果

为0,当前线程将一直占有CPU,直到更高优先级线程要求占有CPU。这个调度算法好像是很有效、很完美

,但却存在着一种情况,当这种情况发生时程序会死锁。举例来说:一个应用程序包含两个线程,线程1

是高优先级,线程2是低优先级,当线程1运行过程中处于阻塞时,线程2得到时间片,线程2这次进入了一

个临界区,我们都知道临界区内的资源是不会被其它线程访问的,当线程2正运行时,线程1已经从阻塞状

态转变为运行状态,而这次线程1却要访问线程2的资源,这个资源却被临界区锁定,那么线程1只能等待

,等待线程2从临界区中运行结束并释放资源的独占权。但是线程2却永远不会得到时间片,因为CE保证高

优先级线程会先运行。这时程序就会处于死锁状态。当然系统不会死锁,因为还有更高优先级的线程、驱

动程序在运行。对于这种情况,CE采取优先级转换的办法来解决。就是当发生这种情况时,内核将线程2

的优先级提高到线程1的优先级水平。这样线程2就可以执行完临界区代码了,线程1也就能够访问资源了

。然后内核再恢复线程2原来的优先级。
  挂起一个线程使用SuspendThread函数。参数只有一个――线程的句柄。要说明的是如果要挂起的线

程正调用一个内核功能,这时执行此函数可能会失败。需要多次调用此函数直到函数返回值不为

0xFFFFFFFF,说明挂起成功。恢复线程使用ResumeThread函数。参数也只有一个――线程的句柄。
  关于线程本地存储器和纤程,实际用到的时候非常少,这部分知识可以参考《Windows核心编程》。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值