线程
一个进程拥有的线程理论上是没有限制的,只与当前可用的内存有关,也就是说只要内存够用,就可以创建线程。进程中的线程共享进程所占有的资源,包括地址空间和代开的文件等内核对象。线程出了占有内存外,还占有其他资源,如处理器的寄存器和栈,每个线程都有自己独立的栈,这些资源构成了线程的上下文。
在核心态,线程可以访问操作系统所有的资源。一般来说,操作系统线程和中断服务例程运行在核心态,应用程序和设备驱动程序的中断服务例程运行在用户态。wince运行所有的进程运行在核心态,虽然不稳定,但是可以提高效率。
创建一个线程:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 不支持,NULL
DWORD dwStackSize, // 通常默认值
LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址(很重要,基本上也就是线程要做的事情,可以是下面的ThreadProc,做的事情就在那个线程函数中实现了)
LPVOID lpParameter, //线程参数(线程要做事情,总得给它传点东西,否则不知道如何干)
DWORD dwCreationFlags, // 线程创建属性
LPDWORD lpThreadId // 线程ID(线程的名字了)
);
线程函数定义:
DWORD WINAPI ThreadProc(
LPVOID lpParamerter//参数指针
);
调度
wince是一个抢占式多任务操作系统。调度程序使用基于优先级的时间片算法对线程进行调度。线程优先级多达256个,0最高,255最低。通常应用程序只须使用248-255的优先级,比较高的优先级供驱动程序和内核使用。
wince的优先级映射
优先级 |
组件 |
优先级 |
组件 |
0-19 |
高于驱动程序的实时 |
145 |
ps2键盘 |
20 |
图形垂直回描 |
148 |
ircomm |
99 |
电源管理唤醒线程 |
150 |
tapi |
100-108 |
usb 串口 ohci uhci
|
248 |
电源管理 |
109-129 |
红外 ndis 触摸屏 |
249 |
鼠标 pnp power wavedev |
130 |
内核无关传输层 |
250 |
wavapi |
131 |
VMini |
251 |
正常 |
132 |
cxport |
252-255 |
应用程序 |
同步(看些例子很容易懂)
1、Mutex
2、Semaphore
3、Event
4、Critical Section
5、互锁函数
进程间通信
wince提供了很多进程间通信的方式,在这里主要说一下文件映射和点对点消息队列。
1、剪贴板:可使用剪切板函数在不同的进程间复制数据。但是一般只适合图形界面的程序,而且通常剪贴板都是由用户操作完成的。
2、com/dcom 通过com组件的代理或存根方式进行进程间数据的交换,但是只能在调用接口函数时传送数据;通过dcom可以在不同主机间传送数据。
3、网络套接字:通过计算机网络,可在相同主机或不同主机间交换数据。
4、WM_COPYDATA消息:通过向进程发这个消息,将数据放在参数中给其他进程传递数据。只适合窗口消息队列的进程。
文件映射:
文件映射又叫内存映射文件。通过内存映射文件可在进程的共享虚拟地址空间内保留一个地址空间的区域,同时将文件所在的物理内存映射到次区域。这样只需要对虚拟内存做读写操作,剩下的就有操作系统做了。wince中内存映射文件会被映射到4gb的虚拟地址空间0x42000000-0x7fffffff的进程区域中,因此实现了多个进程之间的通信。
点对点消息队列:
是常用的系统模块之间进行通信的方式。它很好地附和了操作系统原理中生产者-消费者的模型。消息队列通常是一个先进先出的队列结构,当一个进程吧消息写入队列,需要此消息的其他进程,就可从队列中取得消息,从而达到进程间通信的目的。
wince下的消息队列实现中,有以下特色:
1、消息可以为任何类型,事实上消息只是一个任意大小的内存缓冲区。这非常有利于在不同进程之间进行数据交换。
2、消息队列还可以用来进行同步。
3、消息是没有优先级的,对于同一个队列,所有的消息都严格按照先进先出的方式进出
4、wince中的消息队列是基于点对点操作,它不能用来进行广播
内存管理
wince采用层次化的结构内存管理。从下到上依次分别是物理内存、虚拟内存、逻辑内存和c或c++语言运行库。内存管理的每一层都会向外提供一些编程接口函数,这些编程接口可被上一层使用,也可直接被应用程序使用。
物理内存:
wince中RAM、ROM和Flash Memory都被看做物理内存,而不仅仅是传统意义上的,只有RAM被认为是物理内存。
RAM 关机后,可以用电池保存上次的一些状态,如果开机,可以恢复上次的页面。
ROM可以断电永久存储,和硬盘一样。
ROM的替代品flash memory(闪存)。比ROM最大的优点就是可擦写。flashmemroy可以分为and、nand、nor、dinor等。其中nand和nor是目前主流类型。nor的缺点是容量小。nand优点是容量大,但是速度慢。
虚拟内存:
wince是32位的操作系统,也有4GB的虚拟寻址能力,但是与winXP的每个进程独享4GB虚拟地址空间不同,wince是共享4GB的空间。
wince系统支持两种页的大小:1KB和4KB。wince中虚拟内存的申请分为保留和提交两个过程。虚拟地址空间的保留是以64KB为边界的。也就是说,任何一次虚拟内存申请都会返回一个64KB整数倍的地址。但是把虚拟内存提交到物理内存是以页为粒度的。
管理虚拟内存的硬件是内存管理单元MMU。MMU负责把虚拟地址映射到物理地址,并提供一定的保护。
wince将4GB的虚拟地址空间分为若干个slot,每个32MB,slot编号从0-63.slot0是用于映射当前处理器上执行的进程;slot1有XIP(本地执行)的dll代码使用。slot2-32是wince每个进程的32MB的虚拟地址空间,其中slot2被filesys.exe占有。也就是理论上wince可以有30几个进程,但是用户可以用的只有不到30个。
slot33-63对应的虚拟地址空间0x42000000-0x7fffffff。这块是有所有进程共享的。slot63是用来保存dll资源的。
从0x80000000开始时wince内核的虚拟地址空间。虚拟地址0x80000000-0x9fffffff一段用来静态映射所有物理地址。wince会把物理内存1:1地映射到这段虚拟地址上。这段地址一共512MB,这也是wince支持的物理地址的最大值是512MB的原因。
逻辑内存:
逻辑内存分为堆和栈两种。对是进程中一块连续的虚拟地址空间,应用程序可以在堆上动态地进行内存申请和释放。申请堆是以字节为单位,与页的大小无关,所以每次可以申请4字节或者8字节。
wince为每个进程分配了60kb的栈,并把栈顶2KB用来判断是否栈满,因此每个线程用户可用58KB。
c或c++语言运行库:
malloc/free new/delete
localAlloc()等
存储管理和文件系统
对象存储:
是一个被filesys.exe控制的内存堆,包括:
RAM文件系统
注册表
ce数据库
文件系统:
RAM文件系统:直接挂在根目录下
ROM文件系统:\windows目录下。windows目录中的内容一般就是romimage.exe最终生成的windowsCE运行时镜像的内容,这也就意味着windows目录里面的文件通常都是只读的,用户不能修改和删除。
可安装文件系统:
注册表:
用来保存应用程序、驱动程序和用户设定的一些配置信息。
存储管理器:
主要功能是管理所有的外存设备。从逻辑上讲,它包含设备驱动管理器、分区管理器、和文件系统驱动管理器。
下面以读取磁盘上的一个文件为例,看看wince的存储管理器是如何对存储设备进行管理的。
1、应用程序readfile请求操作系统读操作。coredll中断并被nk截获,然后到filesys执行。
2、filesys会通过对象存储来解析路径,查找此文件的位置,然后发现文件在外存上。
3、filesys通过文件系统驱动程序在外存上查找此文件,如果这个文件系统包含多个分区,还要调用分区驱动程序在分区上查找文件,如果找到,则进行读写。
4、真正的读写是在块设备驱动程序进行的。
用户界面与图形系统
gwes的3个关键的模块:图形、窗口、事件