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

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

进程是资源申请、调度和独立运行的单位,因此,它试用系统中的运行资源;
而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此它不占用系统资源。

进程由2部分组成:
1.内核对象          操作系统用来管理进程的内核对象。   内核对象也就是系统用来存放有关进程的统计信息的地方。
2.地址空间          地址空间包含所有可执行模块或DLL模块的代码和数据,还包含动态内存分配的空间。 
                              比如:线程堆栈和堆分配空间

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

单个进程可能包含若干线程,这些线程都是“同时”执行进程地址空间中的代码。

每个进程至少拥有一个线程,来执行地址空间中的代码。
当创建一个进程时,系统会自动创建这个进程的第一个线程,此线程称为主线程。
此后,主线程再创建其它线程。

进程地址空间:

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

每个进程都有它的私有地址空间。
进程A可能有一个存放在A的地址空间中的数据结构,地址是0x12345678;
进程B有一个完全不同的数据结构存放在B的地址空间,地址是0x12345678;
当进程A的线程访问地址为0x12345678的内存时,这些线程访问的是进程A的数据结构;
当进程B的线程访问地址为0x12345678的内存时,这些线程访问的是进程B的数据结构;
进程A的线程不能访问进程B的地址空间中的数据结构,反之亦然。

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

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

线程:
线程由2部分组成:
1.线程的内核对象:
操作系统用它来对线程实施管理。
内核对象也是系统用来存放线程统计信息的地方。
2.线程堆栈:
它用来维护线程在执行代码时需要的所有参数和局部变量。

当创建线程时,系统创建一个线程内核对象。
该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结果。
可以将线程内核对象视为由关于线程的统计信息组成的一个小型数据结构。

线程总是在某个进程环境中创建。系统从进程的地址空间中分配内存,供线程的堆栈使用。
新线程运行的进程环境与创建线程的环境相同。因此,新线程可以访问进程的内核对象的所有句柄、
进程中的所有内存和在这个相同进程中的所有其他线程的堆栈。
这使得单个进程的多个线程能够非常容易的相互通信。

线程只有一个内核对象和堆栈,保留的记录很少,所以所需的内存也很小。

因为线程需要的开销比进程少,因此编程中经常用多线程来解决问题,避免开启新的线程。


线程运行:
操作系统为每个运行线程安排一定的CPU时间——时间片。
系统通过一种循环的方式为线程提供时间片,每个线程在自己的时间内运行,因时间片相当短,
所以给用户的感觉就好像多线程在同时运行一样。

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

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

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

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