第4章 Hello China的线程
4.1 线程概述
线程是Hello China操作系统的任务模型,在本章中,我们对这个任务模型进行详细描述,并对其实现机制和代码进行分析。在此之前,有必要对操作系统中关于线程、进程和任务的一些基本概念进行描述,以便读者更好地理解本章内容。
4.1.1 进程、线程和任务
进程是操作系统演进中的具有革命意义的概念,所谓进程,比较通俗的一个说法就是“一个运行起来的程序”,也就是说,一个进程,首先是一个程序,即一段代码,而且是一段已经运行起来的代码。比如,位于磁盘上的应用程序不是进程,因为它还没有运行起来,一旦该程序运行起来(比如,在命令行界面中输入该程序的名字及相关参数,然后敲回车键),就可以称为进程了。总之,一个进程有下列特性。
(1)首先是一个程序,即是一段可执行的代码(这段代码可能位于内存中,也可能位于存储介质上);
(2)该程序正在运行,即已经被操作系统加载到内存中(或者本来就位于内存中),并创建了相应的控制结构(比如,进程控制块、地址空间等)。
一般情况下,一个进程有自己独立的地址空间,比如,在32位硬件平台上,进程的地址空间是4GB。可执行代码可以访问这个地址空间内的任何数据(不考虑操作系统的保护机制),但不能访问其他进程的数据,因为不同的进程其地址空间是不重叠的。
线程则是归属于进程的可调度单位。一般情况下,一个进程由多个线程组成,线程是操作系统能够知晓的最小的调度单位,而且一般情况下,操作系统都是按照线程来调度的。属于同一个进程的多个线程共享进程的地址空间,这样线程之间就可以很容易地通过这个公共的地址空间进行通信。每个线程都有自己的堆栈和上下文,用于保存运行过程数据。而任务是嵌入式操作系统中的一个概念,其本质就是一个线程,但特别的是,任务是一个一直运行的循环,一旦启动,就一直运行,不会中途退出(除非发生异常被操作系统强行中止,或者被人工强行中止)。由于任务本质上是一个线程,具备线程所有的特点,而线程的内涵更丰富一些,因此,在Hello China的实现中,只引用了线程的概念,没有引入任务概念。实际上,把一个线程的功能函数编码成一个死循环,该线程就成了一个任务。比如,下列函数就可以作为一个任务运行。
DWORD TaskRoutine(LPVOID lpData) { …… while(TRUE) { GetMessage(…); //Get message from message queue. ProcessMsg(…); //Process message. }; return 0L; }
该函数一旦被投入运行,就以循环的方式检查自己的消息队列,若有消息,则做进一步处理,然后又进入新一轮循环。