以下是我以前写的一点东西,希望对你有用。在Windows操作系统中可以同时执行多个程序,比如打开一个资源管理器和多个IE浏览器,同时使用播放器播放音乐,后台可能同时还有杀毒软件防火墙在运行,这里的每一个运行的程序都是一个进程。严格地说,这种说法是不准确的,程序一般是指保存在外部存储器(一般为硬盘)中的代码文件,当程序被执行时,系统会先在内存中为其分配一块空间,再把其代码复制到该空间中执行,这个在由系统分配的内存空间中执行的程序才是进程。一个程序可能同时存在多个相应的进程,如同时打开多个IE浏览器,每一个浏览器窗口都是一个进程,都拥有自己独立的内存空间,而它们都来自于同一个程序。
线程可以看作进程概念下的进一步细分,它的很多特征都非常类似于进程。例如,整个操作系统由多个进程组成(包括操作系统进程),而一个进程由多个线程组成(一般处理单任务的进程只含有一个线程);在整个操作系统占用CPU期间,操作系统分配CPU时间给每一个进程,而在一个进程占用CPU期间,进程分配CPU时间给每一个线程(如何分配即是本章的主要内容之一);进程占用整个内存空间的一部分,而线程占用其所属进程占用的内存空间的一部分;进程由代码、数据和运行环境组成,而线程也由这三者组成。
进程与线程的不同之处在于,每个进程都是独立的,它仅在分配给它的内存空间中运行,有自己专属的代码和数据,不能访问其它进程的数据(就算另一个进程来自于同一个程序),进程间的通信必须通过操作系统传达,进程有权不接受其它进程(操作系统关键进程除外)发出的消息;而线程允许代码和数据的共享,一个线程可以使用其它线程的代码,也可以访问其它线程的数据(这可能带来数据冲突的问题),使得线程间的通信比进程间的通信更为方便快捷(但同时也会带来某些问题)。

解决方案 »

  1.   

    //-- jiangnanyuzi(江南愚子) 
    在整个操作系统占用CPU期间,操作系统分配CPU时间给每一个进程,而在一个进程占用CPU期间,进程分配CPU时间给每一个线程(如何分配即是本章的主要内容之一);
    //--我不太同意你的这个说法,按照你的说法:CPU分配时间给进程,进程再分配时间给进程下的每个线程,那么一个具有多个线程进程和一个单线程的进程相比的话,不可能会获得更多的cpu时间。
    比喻:有进程A 、进程B,进程A只有一个线程A1,进程B有3个线程B1 B2 B3.CPU分配给每个进程的CPU时间为t.假定cpu使用轮循的方式分配cpu时间给近程。那么经过一次轮循后,A1的cpu使用时间为t,B1 B2 B3的cpu使用时间均为t/3,那么进程A B使用cpu的时间相当均为t.
    那么多线程还有什么意义?多线程不就是为了有机会占用更多的cpu时间的吗?我觉得操作系统应该是以线程为单位来分配cpu时间的,而不是以进程为单位。像上例中,经过一次轮循后,进程A如果占用了t的cpu时间,那么进程b可能占用了3t的cpu时间
      

  2.   

    进程与线程
    进程和线程是两个相对的概念,通常来说,一个进程可以定义程序的一个实例(Instan
    ce)。在Win32中,进程并不执行什么,它只是占据应用程序所使用的地址空间。为了让
    进程完成一定的工作,进程必须至少占有一个线程,正是这个线程负责包含进程地址空
    间中的代码。实际上,一个进程可以包含几个线程,它们可以同时执行进程地址空间中
    的代码。为了做到这一点,每个线程有自己的一组CPU寄存器和堆栈。每个进程中至少有
    一个线程在执行其地址空间中的代码。如果没有线程执行进程地址空间中的代码,进程
    也就没有继续存在的理由,系统将自动清除进程及其地址空间。
    多线程的实现原理
    创建一个进程时,它的第一个线程称为主线程(Primary thread),由系统自动生成。
    然后可以由这个主线程生成额外的线程,而这些线程,又可以生成更多的线程。
    在运行一个多线程的程序时,从表面上看,这些线程似乎在同时运行。而实际情况并非
    如此,为了运行所有的这些线程,操作系统为每个独立线程安排一些CPU时间。单CPU操
    作系统以轮转方式向线程提供时间片(Quantum),每个线程在使用完时间片后交出控制
    ,系统再将CPU时间片分配给下一个线程。由于每个时间片足够的短,这样就给人一种假
    象,好像这些线程在同时运行。创建额外线程的唯一目的就是尽可能地利用CPU时间。
    多线程的问题
    使用多线程编程可以给程序员带来很大的灵活性,同时也使原来需要复杂技巧才能解决
    的问题变得容易起来。但是,不应该人为地将编写的程序分成一些碎片,让这些碎片按
    各自的线程执行,这不是开发应用程序的正确方法。
    线程很有用,但当使用线程时,可能会在解决老问题的同时产生新问题。例如要开发一
    个字处理程序,并想让打印功能作为单独的线程自己执行。这听起来是很好的主意,因
    为在打印时,用户可立即返回,开始编辑文档。但这样一来,在该文档被打印时文档中
    的数据就有可能被修改,打印的结果就不再是所期望的内容。也许最好不要把打印功能
    放在单独的线程中,不过如果一定要用多线程的话,也可以考虑用下面的方法解决:第
    一种方法是锁定正在打印的文档,让用户编辑其他的文档,这样在结束打印之前,该文
    档不会作任何修改;另一个方法可能更有效一些,即可以把该文档拷贝到一个临时文件
    中,打印这个临时文件的内容,同时允许用户对原来的文档进行修改。当包含文档的临
    时文件打印完成时,再删去这个临时文件。
    通过上面的分析可以看出,多线程在帮助解决问题的同时也可能带来新问题。因此有必
    要弄清楚,什么时候需要创建多线程,什么时候不需要多线程。总的来说,多线程往往
    用于在前台操作的同时还需要进行后台的计算或逻辑判断的情况,而对于GUI(图形用户
    接口),除了开发MDI(多文档界面)应用程序外,应尽量不使用多线程。
    线程的分类
    在MFC中,线程被分为两类,即工作线程和用户界面线程。如果一个线程只完成后台计算
    ,不需要和用户交互,那么可以使用工作线程;如果需要创建一个处理用户界面的线程
    ,则应使用用户界面线程。这两者的主要区别在于,MFC框架会给用户界面线程增加一个
    消息循环,这样用户界面线程就可以处理自己消息队列中的消息。这样看来,如果需要
    在后台作一些简单的计算(如对电子表格的重算),则首先应考虑使用工作线程,而当
    后台线程需要处理比较复杂的任务,确切地说,当后台线程的执行过程会随着实际情况
    的不同而改变时,就应该使用用户界面线程,以便能对不同的消息作出响应。
    线程的优先级
    当系统需要同时执行多个进程或多个线程时,有时会需要指定线程的优先级。线程的优
    先级一般是指这个线程的基优先级,即线程相对于本进程的相对优先级和包含此线程的
    进程的优先级的结合。操作系统以优先级为基础安排所有的活动线程,系统的每一个线
    程都被分配了一个优先级,优先级的范围从0到31。运行时,系统简单地给第一个优先级
    为31的线程分配CPU时间,在该线程的时间片结束后,系统给下一个优先级为31的线程分
    配CPU时间。当没有优先级为31的线程时,系统将开始给优先级为30的线程分配CPU时间
    ,以此类推。除了程序员在程序中改变线程的优先级外,有时程序在执行过程中系统也
    会自动地动态改变线程的优先级,这是为了保证系统对终端用户的高度响应性。比如用
    户按了键盘上的某个键时,系统就会临时将处理WM_KEYDOWN消息的线程的优先级提高2到
    3。CPU按一个完整的时间片执行线程,当时间片执行完毕后,系统将该线程的优先级减
    1。
    线程的同步
    在使用多线程编程时,还有一个非常重要的问题就是线程同步。所谓线程同步是指线程
    之间在相互通信时避免破坏各自数据的能力。同步问题是由前面说到的Win32系统的CPU
    时间片分配方式引起的。虽然在某一时刻,只有一个线程占用CPU(单CPU时)时间,但
    是没有办法知道在什么时候,在什么地方线程被打断,这样如何保证线程之间不破坏彼
    此的数据就显得格外重要。在MFC中,可以使用4个同步对象来保证多线程同时运行。它
    们分别是临界区对象(CCriticalSection)、互斥量对象(CMutex)、信号量对象(CS
    emaphore)和事件对象(CEvent)。在这些对象中,临界区对象使用起来最简单,它的
    缺点是只能同步同一个进程中的线程。另外,还有一种基本的方法,本文称为线性化方
    法,即在编程过程中对一定数据的写操作都在一个线程中完成。这样,由于同一线程中
    的代码总是按顺序执行的,就不可能出现同时改写数据的情况。