1、 操 作 系 统 课 程 设 计 论 文 题题 目目 多线程管理与线程通信 学学 院院 专专 业业 计算机科学与技术 学生姓名学生姓名 导师姓名导师姓名 内容摘要 随着科学技术的发展,通信变得越来越重要,如何实现不同主机之间的通信,成 为越来越多人关心的问题。本次课程通过实现两个端口,一个服务端口,通过多 线程为客户端提供了一个交流的平台。 客户通过客户端建立用户, 进行信息交流。 1、理解线程 要讲解线程,不得不说一下进程,进程是应用程序的执行实例,每个进程是 由私有的虚拟地址空间、代码、数据和其它系统资源组成。进程在运行时创建的 资源随着进程的终止而死亡。线程的基本思想很简单,它是一个独立
2、的执行流, 是进程内部的一个独立的执行单元,相当于一个子程序,它对应于 Visual C+ 中的 CwinThread 类对象。单独一个执行程序运行时,缺省地包含的一个主线程, 主线程以函数地址的形式出现,提供程序的启动点,如 main()或 WinMain() 函数等。当主线程终止时,进程也随之终止。根据实际需要,应用程序可以分解 成许多独立执行的线程,每个线程并行的运行在同一进程中。 一个进程中的所有线程都在该进程的虚拟地址空间中, 使用该进程的全局变 量和系统资源。 操作系统给每个线程分配不同的 CPU 时间片, 在某一个时刻, CPU 只执行一个时间片内的线程,多个时间片中的相应线程在
3、 CPU 内轮流执行,由于 每个时间片时间很短, 所以对用户来说, 仿佛各个线程在计算机中是并行处理的。 操作系统是根据线程的优先级来安排 CPU 的时间,优先级高的线程优先运行,优 先级低的线程则继续等待。 线程被分为两种:用户界面线程和工作线程(又称为后台线程) 。用户界面 线程通常用来处理用户的输入并响应各种事件和消息,其实,应用程序的主执行 线程 CWinAPP 对象就是一个用户界面线程,当应用程序启动时自动创建和启动, 同样它的终止也意味着该程序的结束,进程终止。工作线程用来执行程序的后台 处理任务,比如计算、调度、对串口的读写操作等,它和用户界面线程的区别是 它不用从 CWinTh
4、read 类派生来创建,对它来说最重要的是如何实现工作线程任 务的运行控制函数。 工作线程和用户界面线程启动时要调用同一个函数的不同版 本;最后需要读者明白的是,一个进程中的所有线程共享它们父进程的变量,但 同时每个线程可以拥有自己的变量。 2、线程的管理和操作 (一)线程的启动 创建一个用户界面线程,首先要从类 CwinThread 产生一个派生类,同时必 须使用 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 来声明 和实现这个 CwinThread 派生类。第二步是根据需要重载该派生类的一些成员函数如: ExitInstance() 、InitInstan
5、ce() 、OnIdle() 、PreTranslateMessage()等 函 数 。 最 后 调 用AfxBeginThread() 函 数 的 一 个 版 本 : CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ) 启动该用户界面线程,其 中第一个参数为指向定义的用
6、户界面线程类指针变量, 第二个参数为线程的优先 级, 第三个参数为线程所对应的堆栈大小, 第四个参数为线程创建时的附加标志, 缺省为正常状态,如为 CREATE_SUSPENDED 则线程启动后为挂起状态。 对于工作线程来说,启动一个线程,首先需要编写一个希望与应用程序的其 余部分并行运行的函数如 Fun1(),接着定义一个指向 CwinThread 对象的指针变 量*pThread,调用 AfxBeginThread(Fun1,param,priority)函数,返回值赋给 pThread 变量的同时一并启动该线程来执行上面的 Fun1()函数,其中 Fun1 是 线程要运行的函数的名字,也既是上面所说的控制函数的名字,param 是准备传 送给线程函数 Fun1 的任意 32 位值,priority 则是定义该线程的优先级别,它 是预定义的常数,读者可参考 MSDN。 (二)线程的优先级 以下的 CwinThread 类的成员函