进程和线程的相关概念如同步、通信等概念之间经常搞混,这里做一下解释说明:
首先解释下:进程与线程之间的关系
(1)为什么有了进程后,还引入线程?
答:简单说:由于进程独立占用资源,创建多进程需要的资源多且占用空间大,同时多进程切换也就更速度慢且复杂;而线程正是为了避免进程的这些缺陷而提出的,即:线程共享地址空间(进程资源),从而多线程占用资源少,多线程切换速度快且简单。
(2)相互关系
答:如下:
①进程和线程均可并发执行;
②一个进程至少有一个线程,线程从属于进程;
③引入线程前,进程是CPU调度的基本单位和资源分配基本单元;引入线程后,进程是资源分配的基本单元,线程是CPU调度的基本单位;
(3)线程和进程的区别和应用场景见下表:
根本区别:进程有独立的地址空间,线程共享地址空间;
其他区别均由根本区别引起,如下表:
补充一个区别:
线程私有包括栈、寄存器、状态、程序计数器;线程间共享的包括堆,地址空间,全局变量,静态变量;
进程私有地址空间、堆、全局变量以及栈、寄存器等资源;进程共享代码段、进程公共数据、以及进程目录、进程ID等;
根据上表,可以得出进程与线程的应用场景:
①需要频繁创建销毁的优先用线程(线程创建销毁开销小,过程简单,速度快);
②需要进行大量计算的优先使用线程(计算量大意味着要耗费大量CPU资源,必然需要频繁切换,多线程适合);
③强相关的处理用线程,弱相关的处理用进程(强相关必然有更多相互通信,多线程通信简单,所以适合);
④可能要扩展到多机分布的用进程,多核分布的用线程(见表);
进程/线程间的同步与通信
(1)先解释下同步与互斥的关系:
互斥好理解;就是一个进程或线程在占用一资源时,其他进程或线程均不可访问;
同步通俗讲:就是在互斥的基础上保证进程或线程对资源的有序访问;
(2)进程的同步机制和通信机制
①进程同步机制:信号量、管程;
②进程间通信机制:共享内存、消息传递(直接传递和间接传递)、管道(无名管道、有名管道)
经常把进程同步和通信搞混,实际两者关系是包含关系:因为进程同步只可以传递少量数据,所以进程同步机制实际上是低级的进程通信机制,而我们现在说的进程通信机制实际上是高级的通信机制;
更详细完整的进程间通信机制如下图:
注:RPC——远程过程调用协议
③简要解释各种进程同步和通信方式:
信号量——是通过一对同步操作(wait(S)和singal(S)),又叫PV操作,实现同步。当s≤0时,表示资源被占用,当前进程执行等待wait(S)。否则执行s=s-1后进入singal(S),获取资源。其传输数据量少,一般用于同步而非通信;
管程——是为了避免信号量的缺陷(每一个进程都需要自备一对PV操作,给系统管理带来麻烦)而提出的。管程由共享数据结构体和对共享数据的一组操作组成,进程无需自备操作。但注意管程有一个队列,用于保存请求进程,每次只需允许一个进程进入,从而保证互斥;
管道——一种半双工通信模式,实际就是一个共享文件,每一时刻只可以对文件有一种操作——写或者读;共享内存——该进程通信方式没有自带的同步机制,需要自己实现同步;
套接字(socket):常用于不同主机之间的通信;
(3)线程间同步和通信机制
①线程间同步机制:锁机制(互斥锁、读写锁)、条件变量、信号量;
②线程间通信机制:如上面进程通信机制所述,线程同步机制也属于低级通信机制,这里介绍高级的线程通信机制,主要包括三个,分别是:全局变量、消息机制、事件(CEvent);
③简要介绍下上述线程同步与通信方式:
全局变量——这个容易理解,也是最常用的方式,通过修改和读取全局变量来实现多个线程之间通信;
消息机制——windows程序设计中,都有线程间的消息通信机制。常用的Message通信的接口主要有两个:PostMessage和PostThreadMessage,PostMessage为线程向主窗口发送消息。而PostThreadMessage是任意两个线程之间的通信接口;
事件(CEvent)——CEvent为MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步。