windows核心编程之进程&线程

在前一章总结内核对象时提到过进程内核对象和线程内核对象,但是对进程线程以及进程内核对象和线程内核对象在其中的意义还不是很清楚,下面就详细说说进程与线程,进程内核对象和线程内核对象,进程与进程内核对象,线程与线程内核对象之间的千丝万缕的联系。

 

在开始之前,提出两个面试中经常遇到的简单问题:(1)进程与线程的联系和区别 (2)在多线程编程中为什么要考虑同步互斥操作?两个问题的解答在本章最后给出。

 

1、进程与线程

      进程是一个具有独立功能的程序关于某个数据集合的一次运行活动,进程是一个执行中的程序,是一个活动的实体,是线程的容器,这都是进程的定义。举例来说,打开电脑中的一个可执行的应用程序,比如IE浏览器,这就是一个进程,当对IE浏览器执行操作就是其中的一个线程。

     进程是不活跃的,真正活跃的是进程中的线程,一个进程中至少有一个线程,那就是主线程,通过主线程可以创建多个线程,也就是以后会总结到的多线程。

   进程包括进程内核对象和进程地址空间,同样线程也是。

  (1)线程内核对象:线程内核对象是一个小的数据结构体,维护了与线程有关的各种属性,如线程的使用次数,对象是否被通知,线程的暂停计数等。

  (2)线程堆栈:在线程内核对象创建完成后,系统会分配给线程堆栈内存,该内存来自于进程的地址空间,线程堆栈内保存着函数指针及数据等信息。

2、线程的创建过程

在windows中调用线程创建函数CreateThread函数可以创建一个线程,确切的说是创建了一个线程内核对象,线程内核对象的相关属性被设置,其中线程内核对象的使用计数被设置为2,暂停计数为1,且为未通知状态。

线程内核对象创建完成之后分配线程堆栈,进而执行线程代码。

 

3、线程的终止运行过程

   当线程函数正常返回后,线程函数中所有创建的C++对象及内存释放,进而线程堆栈释放,线程内核对象的使用计数递减,通过closeHandle关闭该内核对象。当使用计数为0时,该内核对象会被系统撤销。

 

4、问题解答

(1)进程与线程的联系和区别

进程是线程的容器,一个进程至少有一个线程。

(2)为什么会有同步互斥

进程中的线程共享进程的地址空间以及其他各种资源,而windows操作系统又是资源抢占式的,因此在一个进程中有多个线程时,就可能会导致多个线程抢占同一资源,并且不可控,因此在多个线程编程中要设置同步互斥,以保证在某一时刻资源被某一个线程占有,其他资源无权占有。

什么是线程的同步呢?本人认为线程同步并不是线程要同步执行,而是针对多个线程的共享资源来说的,即多个线程对共享资源的拥有是同步的,举一个简单的例子:线程thread1和线程thread2共同访问一个变量 globalvar且为其做加1操作,即如下所示

int globalvar = 0;

void thread1()
{

	globalvar ++;
}

void thread2()
{
	globalvar ++;
}

对一个变量做++操作需要经过以下三个步骤:
(1)将变量从静态存储空间中取出

(2)将变量加入到寄存器中并且加1

(3)将加1后变量放入静态存储空间中

假设thread1正在执行步骤3,此时thread2同样开始执行加1操作,这时thread2取出的数据为0而不是thread1执行加法之后的1,这就是thread1和thread2没有同步,因此需要保证多个线程对资源的拥有是同步的。

要保证线程同步有很多种方法,待后面介绍。

 

 

你可能感兴趣的:(多线程编程)