第8章进程与线程
第8章 进程与线程
Win32操作系统平台提供了强大的多任务功能,其中 “进程”( Process)和“线程”( Thread是其控制多任务的 两个重要概念。早期的 Windows3x只能依靠应用程序之间 的协同来实现协同式多任务,而 Windows95/NT实行的是 抢占式多任务。 在Win32( Windows95NT中,每一个进程可以同时执 行多个线程,这意味着一个程序可以同时完成多个任务。 对于象通信应用程序那样的既要进行耗时的工作,又要保 持对用户输入响应的应用来说,使用多线程是最佳选择。 进程使用多个线程时,需要采取适当的措施来保持线程 间的同步
Win32操作系统平台提供了强大的多任务功能,其中 “进程”(Process)和“线程”(Thread)是其控制多任务的 两个重要概念。早期的Windows 3.x只能依靠应用程序之间 的协同来实现协同式多任务,而Windows 95/NT实行的是 抢占式多任务。 在Win 32(Windows 95/NT)中,每一个进程可以同时执 行多个线程,这意味着一个程序可以同时完成多个任务。 对于象通信应用程序那样的既要进行耗时的工作,又要保 持对用户输入响应的应用来说,使用多线程是最佳选择。 当进程使用多个线程时,需要采取适当的措施来保持线程 间的同步
进程与子进程 进程( process是计算机操作系统中的概念。进程可以理解为:程 序在给定的初始状态和内存区域中,能共行执行的一次“计算” 亦即,进程是可以和其它程序共行执行的,程序的一次执行。进程 有独自的内存空间、程序代码、信息以及一堆大大小小的系统资源。 另外,进程之间也有父子关系,产生进程的进程是“父进程”,被 产生的进程是“子进程”,通常父进程对子进程有控制权,同时子 进程也可以存取父进程的资源
进程与子进程 进程(process)是计算机操作系统中的概念。进程可以理解为:程 序在给定的初始状态和内存区域中,能共行执行的一次“计算”, 亦即,进程是可以和其它程序共行执行的,程序的一次执行。进程 有独自的内存空间、程序代码、信息以及一堆大大小小的系统资源。 另外,进程之间也有父子关系,产生进程的进程是“父进程”,被 产生的进程是“子进程”,通常父进程对子进程有控制权,同时子 进程也可以存取父进程的资源
创建子进程API函数 下面介绍一个很重要的函数,即 Create Process函数,其原型为: BOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY ATTRIBUTES lp ProcessAttributes LPSECURITY ATTRIBUTES lp Thread Attributes, BOOL bInheritHandles DWORD dwCreation Flags, LPVOID lpEnvironment, LPCTSTR Ip CurrentDirectory, LPSTARTURINFO lpStartuplnfo LPPROCESS INFORMATION Ip ProcessInformation) Create Process()的功能是建立并执行 child process
创建子进程API函数 下面介绍一个很重要的函数,即CreateProcess函数,其原型为: BOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTURINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); CreateProcess()的功能是建立并执行child process
其它函数 本节将介绍一些可以协助我们取得 process相关信息的函数。第一组要 介绍的是最重要的 GetCurent Process(GetCurrentProcesslar ,前者会返回 目前正在执行的 proces也就是调用者)的 handle,后者会返回调用者的 id。 Handle和id有什么不同呢?id只是一个数字,Win32保证不会有第 二个在系统中执行的 process有相同的id,因此,这个数字通常用来鉴 别 process的身份; process handle可就重要了,因为其他与 process关 的函数都需要它来当参数 ● HANDLE GetCurrent Process(VOID) DWORD GetCurrent Processld( VOID) DWORD Get Priority Class(HANDLE hProcess); BOOL SetPriority Class(HANDLE hProcess, DWORD dwPriority Class)
其它函数 本节将介绍一些可以协助我们取得process相关信息的函数。第一组要 介绍的是最重要的GetCurentProcess()GetCurrentProcessId(), 前者会返回 目前正在执行的process(也就是调用者)的handle, 后者会返回调用者的 id。Handle和id有什么不同呢?id只是一个数字,Win32保证不会有第 二个在系统中执行的process拥有相同的id, 因此,这个数字通常用来鉴 别process的身份;process handle可就重要了,因为其他与process有关 的函数都需要它来当参数。 l HANDLE GetCurrentProcess(VOID); l DWORD GetCurrentProcessId(VOID); DWORD GetPriorityClass(HANDLE hProcess); BOOL SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass);
结束 process 如果某个 proces想停止执行,可调用 EXitProcess),不 过我们通常不直接调用它,而是调用C程序库中的exi( exito在自动执行一些清除垃圾的工作之后,再调用 ExitProcesso VOID ExitProcess(UNT uExitCode) 不过,如果 process A想要迫使 process B停止执行, 可以在取得 process B的 handle之后 调用 TerminateProcesso BOOL TerminateProcess(handle hProcess, UNIT u ExitCode)
结束process 如果某个process想停止执行, 可调用ExitProcess(), 不 过我们通常不直接调用它, 而是调用C程序库中的exit(), exit()在自动执行一些清除垃圾的工作之后, 再调用 ExitProcess()。 VOID ExitProcess(UNT uExitCode); 不过, 如果process A 想要迫使process B 停止执行, 可以在取得 process B 的 handle 之 后 , 调 用 TerminateProcess(): BOOL TerminateProcess(HANDLE hProcess, UNIT uExitCode);
进程与线程 前一节我们讨论了进程和子进程的有关概念和编程 技术,实际上在 Windows操作系统环境中, Microsoft提 出了线程是更具有挑战性的编程概念。在 Windows32位 操作系统中,所谓多任务是指系统可以同时运行多个进 程,而每个进程也可以同时执行多个线程。所谓进程就 是应用程序的运行实例。一个进程又可以分为多个线程, 根据线程的运行特征,我们可以把它看成是操作系统分 配CPU时间的基本实体
进程与线程 前一节我们讨论了进程和子进程的有关概念和编程 技术,实际上在Windows 操作系统环境中,Microsoft提 出了线程是更具有挑战性的编程概念。在Windows 32位 操作系统中,所谓多任务是指系统可以同时运行多个进 程,而每个进程也可以同时执行多个线程。所谓进程就 是应用程序的运行实例。一个进程又可以分为多个线程, 根据线程的运行特征,我们可以把它看成是操作系统分 配CPU时间的基本实体
win16的协同多任务 早在16位的 Windows中,应用程序具有对CPU的控制权。只有在调用 GetMessage、 PeekMessage、 WaitMessage或Yild后,程序才有可能把CPU 控制权交给系统,系统再把控制权转交给别的应用程序。如果应用程序在 长时间内无法调用上述四个函数之一,那么程序就一直独占CPU,系统会 被挂起而无法接受用户的输入。 有人可能会想到用 CWinApp: OnIdle函数来执行后台工作,因为该函数是程 序主消息循环在空闲时调用的。但 Onldle的执行并不可靠,例如,如果用户 在程序中打开了一个菜单或模态对话框,那么 OnIdle将停止调用,因为此时 程序不能返回到主消息循环中!在实时任务代码中调用 PeekMessage也会遇 到同样的问题 折衷的办法是在执行长期工作时弹出一个非模态对话框并禁止主窗口,在 消息循环内分批执行后台操作。对话框中可以显示工作的进度,也可以包 含一个取消按钮以让用户有机会中断一个长期的工作。典型的代码如程序 8.1所示。这样做既可以保证工作实时进行,又可以使程序能有限地响应用 户输入,但此时程序实际上已不能再为用户干别的事情了
Win16 的协同多任务 早在16位的Windows中,应用程序具有对CPU的控制权。只有在调用 了GetMessage、PeekMessage、WaitMessage或Yield后,程序才有可能把CPU 控制权交给系统,系统再把控制权转交给别的应用程序。如果应用程序在 长时间内无法调用上述四个函数之一,那么程序就一直独占CPU,系统会 被挂起而无法接受用户的输入。 有人可能会想到用CWinApp::OnIdle函数来执行后台工作,因为该函数是程 序主消息循环在空闲时调用的。但OnIdle的执行并不可靠,例如,如果用户 在程序中打开了一个菜单或模态对话框,那么OnIdle将停止调用,因为此时 程序不能返回到主消息循环中!在实时任务代码中调用PeekMessage也会遇 到同样的问题。 折衷的办法是在执行长期工作时弹出一个非模态对话框并禁止主窗口,在 消息循环内分批执行后台操作。对话框中可以显示工作的进度,也可以包 含一个取消按钮以让用户有机会中断一个长期的工作。典型的代码如程序 8.1所示。这样做既可以保证工作实时进行,又可以使程序能有限地响应用 户输入,但此时程序实际上已不能再为用户干别的事情了
Windows95/T的抢先式多任务 在32位的 Windows系统中,采用的是抢先式多任务,这意味着程 序对CPU的占用时间是由系统决定的。系统为每个程序分配一定的 CPU时间,当程序的运行超过规定时间后,系统就会中断该程序并把 CPU控制权转交给别的程序。与协同式多任务不同,这种中断是汇编 语言级的。程序不必调用象 Peek Message这样的函数来放弃对CPU的控 制权,就可以进行费时的工作,而且不会导致系统的挂起。 例如,在 Windows3x中,如果某一个应用程序陷入了死循环,那么 整个系统都会瘫痪,这时唯一的解决办法就是重新启动机器。而在 Windows95∧NT中,一个程序的崩溃一般不会造成死机,其它程序仍 然可以运行,用户可以按Ctrl+ Alt+Del键来打开任务列表并关闭没有响 应的程序
Windows 95/NT的抢先式多任务 在32位的Windows系统中,采用的是抢先式多任务,这意味着程 序对CPU的占用时间是由系统决定的。系统为每个程序分配一定的 CPU时间,当程序的运行超过规定时间后,系统就会中断该程序并把 CPU控制权转交给别的程序。与协同式多任务不同,这种中断是汇编 语言级的。程序不必调用象PeekMessage这样的函数来放弃对CPU的控 制权,就可以进行费时的工作,而且不会导致系统的挂起。 例如,在Windows3.x 中,如果某一个应用程序陷入了死循环,那么 整个系统都会瘫痪,这时唯一的解决办法就是重新启动机器。而在 Windows 95/NT中,一个程序的崩溃一般不会造成死机,其它程序仍 然可以运行,用户可以按Ctrl+Alt+Del键来打开任务列表并关闭没有响 应的程序
进程与线程 所谓进程就是应用程序的运行实例。每个进程都有自己私有的虚拟 地址空间。每个进程都有一个主线程,但可以建立另外的线程。进程中 的线程是并行执行的,每个线程占用CPU的时间由系统来划分 进程中的所有线程共享进程的虚拟地址空间,这意味着所有线程都可以 访问进程的全局变量和资源。这一方面为编程带来了方便,但另一方面 也容易造成冲突。 虽然在进程中进行费时的工作不会导致系统的挂起,但这会导致进程本 身的挂起。所以,如果进程既要进行长期的工作,又要响应用户的输入, 那么它可以启动一个线程来专门负责费时的工作,而主线程仍然可以与 用户进行交互
进程与线程 所谓进程就是应用程序的运行实例。每个进程都有自己私有的虚拟 地址空间。每个进程都有一个主线程,但可以建立另外的线程。进程中 的线程是并行执行的,每个线程占用CPU的时间由系统来划分。 进程中的所有线程共享进程的虚拟地址空间,这意味着所有线程都可以 访问进程的全局变量和资源。这一方面为编程带来了方便,但另一方面 也容易造成冲突。 虽然在进程中进行费时的工作不会导致系统的挂起,但这会导致进程本 身的挂起。所以,如果进程既要进行长期的工作,又要响应用户的输入, 那么它可以启动一个线程来专门负责费时的工作,而主线程仍然可以与 用户进行交互