程序、进程和线程

程序是计算机指令的集合,以文件的形式存储于磁盘上。

进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身地址空间的一次执行活动。

一个程序可以有多个进程(如打开多个记事本程序),一个进程也可以同时访问多个程序。

进程是资源申请、调度和独立运行的单位,因此,它使用的是系统的运行资源;而程序不是,不占用系统的运行资源。

 

进程由两部分组成:

1.操作系统用来管理进程的内核对象。内核对象:操作系统内部分配的一个内存块,数据结构,不能被应用程序直接访问,需通过windows提供的函数操作。

2.地址空间。包含所有可执行模块或DLL模块的代码和数据,还包含动态内存分配的空间,如线程堆栈和堆分配空间。

 

进程是不活泼的,从来不执行任何东西,只是线程的容器。若要是进程完成某项操作,必须有一个在它环境中运行的线程。此线程负责执行包含在进程地址空间的代码。(进程只是线程的执行环境

 

单个进程可以包含多个线程,这些线程一起“同时”执行进程地址空间中的代码。

每个进程至少拥有一个线程,来执行进程的地址空间的代码。当创建一个进程时,操作系统会自动创建该进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。

 

进程地址空间

系统赋予每个进程独立的虚拟地址空间。对于32位的进程来说,这个地址空间为4GB。

每个进程有它自己的私有地址空间。如,进程A、B均在地址0x12345678上存有数据结构,但A不能访问B,B也不能访问A的数据结构。

4GB是虚拟的地址空间,只是内存的一个范围。在能成功地访问数据不会出现非法访问之前,必须赋予物理存储器(物理内存+页文件),或将物理存储器映射到各个部分的地址空间。

4GB虚拟地址空间中,2GB是内核方式分区,供内核代码、设备驱动程序、设备I/O高速缓冲、非页面内存池的分配和进程页面表的使用呢等,而用户分区使用的地址空间为2GB-64KB,此分区为进程的私有地址空间所在的地方,一个进程不能读取、写入或者以任何方式访问驻留在该分区的另一个进程的数据,对于所有的应用程序来说,该分区是维护进程大部分数据的地方。其余的64KB地址空间为空指针使用的分区。

 

线程的构成:

1.线程的内核对象。操作系统用它对线程实施管理。

2.线程堆栈。用于维护线程在执行代码时所需要的所有参数和局部变量。

image

 

线程运行

操作系统为每一个运行的线程安排一定的CPU时间--时间片。线程在自己的时间段内运行,时间片终止的话,操作系统就会选择另外一个线程继续运行。

系统通过一种循环的方式为线程提供时间片,线程在自己的时间片内运行,时间片很短,给用户的感觉就是同时运行一样。

如果计算机拥有多个CPU,线程就能真正意义上的同时运行。

 

关于多进程和多线程

多线程好处:每个线程均独立的完成一个任务。移植到多CPU后,就可以并发运行

使用多进程的话,每个进程需系统分配私有的4GB的虚拟地址空间。多线程共享同一进程的地址空间。

 

互斥对象(唯一一个与线程内核相关的对象:可将互斥对象的ID设为线程ID

互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权

互斥对象包含一个使用数量,一个线程ID和一个计数器

ID用于标识系统中哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数

互斥对象作用:一个线程在一个时间段内对一种资源进行的访问的时候,其他的线程不能在该时间段内对该资源进行访问

                      (包含共享资源)

ReleaseMutex不能释放不同线程的互斥对象;通过判断线程与互斥对象的ID是否相等,不等则不能释放

哪个线程拥有互斥对象,就应该是那个线程去释放该互斥对象。

互斥对象保护全局变量

结果线程交替:

image

操作系统会在某线程结束后,会自动将线程所拥有的互斥对象的线程ID设为0,并将级数清零。操作系统维护了线程和与线程相关的互斥对象的信息,知道是哪个线程终止,并清理。

 

命名的互斥对象(只运行一个实例

hMutex = CreateMutex(NULL,TRUE,"tickets"); //若此处不具名,则后面不起作用
    if (hMutex)
    {
        if (ERROR_ALREADY_EXISTS == GetLastError() )
        {
            cout<<"only one instance can run!"<<endl;
            return ;
        }
    }


 

posted @ 2013-04-08 19:48  winko  阅读(262)  评论(0编辑  收藏  举报