您的位置:首页 > 其它

OS学习笔记二: 进程线程模型

2017-10-05 14:04 555 查看

一、进程基本概念

1、并发环境与并发程序

并发环境:一段时间 间隔 内,单处理器上有两个或两个以上的程序 同时 处于开始运行但尚未结束的状态 ,并且 次序不是事先确定的

并发程序:在并发环境中执行的程序

2、进程的定义

定义:Process(对CPU 的抽象) 进程是具有独立功能的程序关于 某个数据集合上 的一次运行活动 ,是系统进行 资源分配和 调度 的独立单位又称 任务(Task or Job )

程序的一次执行过程

是正在运行程序的抽象

将一个 CPU 变幻成多个虚拟的 CPU

系统资源以进程为单位分配,如内存、文件、 ……每个具有独立的地址空间

操作系统将 CPU 调度

3、进程控制块 PCB

PCB :Process Control Block

又称 进程描述符、进程属性

操作系统用于管理控制进程的一个专门数据结构

记录进程的各种属性,描述进程的动态变化过程

PCB 是系统感知进程存在的唯一标志

进程与PCB 是一一对应的

进程 表:所有进程的PCB

4、进程描述信息

进程标识符(process ID),唯一,通常是一个整数

进程名,通常基于可执行文件名,不唯一

用户标识符(user ID)

进程组关系

5、进程控制信息

当前状态

优先级(priority)

代码执行入口地址

程序的磁盘地址

运行统计信息(执行时间、页面调度)

进程间同步和通信

进程的队列指针

进程的消息队列指针

6、所拥有的资源和使用情况

虚拟地址空间的状况

打开文件列表

7、CPU 现场信息

寄存器值(通用寄存器、程序计数器PC、程序状态字PSW、栈指针)

指向该进程页表的指针

二、进程状态及状态转换

1、七状态进程模型



2、进程队列

操作系统为每一类进程建立一个或多个队列

队列元素为PCB

伴随进程状态的改变,其PCB 从一个队列进入另一个队列

多个等待队列等待的事件不同

就绪队列也可以多个

单CPU 情况下,运行队列中只有一个进程

三、进程控制

1、进程控制

进程控制操作完成进程各状态之间的转换,由具有特定功能的 原语 完成

进程创建原语

进程撤消原语

阻塞原语

唤醒原语

挂起原语

激活原语

改变进程优先级

……

原语(primitive)完成某种特定功能的一段程序,具有不可分割性或不可中断性

即 原语的执行必须是连续的,在执行过程中不允许被中断

2、进程的创建

给新进程分配一个唯一标识以及进程控制块

为进程分配地址空间

初始化进程控制块

设置默认值 ( 如: 状态为 New ,…)

设置相应的队列指针

如: 把新进程加到就绪队列链表中

UNIX:fork/exec

WINDOWS:CreateProcess

3、进程的撤销

结束进程

收回进程所占有的资源

关闭打开的文件、断开网络连接、 回收 分配的内存、……

撤消该进程的PCB

UNIX:exit

WINDOWS:TerminateProcess

4、进程阻塞

处于运行状态的进程,在其运行过程中期待某一事件发生,如 等待键盘输入、等待磁盘数据传输完成、等待其它进程发送消息 ,当被等待的事件未发生时,由 进程自己执行阻塞原语 ,使自己由运行态变为阻塞态。

UNIX:wait

WINDOWS:WaitForSingleObject

5、UNIX的几个进程控制操作

fork() 通过 复制调用进程 来建立新的进程,是最基本的进程建立过程

exec() 包括一系列系统调用,它们都是通过用一段新的程序代码覆盖原来的地址空间,实现进程 执行代码的转换

wait() 提供初级进程同步 操作 ,能使一个进程等待另外一个进程的结束

exit() 用来终止一个进程的运行

6、UNIX的fork实现

为子进程分配一个空闲 的进程 描述符

proc 结构

分配给子进程唯一标识 pid

以一次一页的方式复制父进程地址空间(Linux 采用了写时

复制技术COW 加快创建进程Copy-On-Write,即创建时将父进程把地址空间的指针传递给子进程,再把地址空间设置为只读,当子进程想往地址空间写东西的时候,操作系统再为子进程开辟一块空间把相应的内容放进去)

从父进程处继承共享资源,如打开的文件和当前工作目录 等

将子进程的状态设为就绪,插入到就绪队列

对子进程返回标识符 0

向父进程返回子进程的 pid

示意代码:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
void main( int argc, char *argv[] )
{
pid_t pid;
pid = fork();           /*  创建一个子进程 */
if ( pid < 0 )          /*  出错 */
{
fprintf( stderr, “ fork failed ” );
exit( -1 );
}else if ( pid == 0 )   /*  子 进程 */
{
execlp( “ / bin / ls ”, “ ls ”, NULL );
}else                                 { /*  父进程 */
wait( NULL );   /*  父 进程等待子进程结束 */
printf( “ child complete ” );
exit( 0 );
}
}




四、深入理解进程概念

1、进程层次结构

UNIX 进程 家族 树 :init 为根

Windows:地位相同

2、进程与程序的区别

进程更 能准确刻画并发,而程序不能

程序 是静态的,进程是动态的

进程有 生命周期的, 有诞生有消亡 ,是短暂 的;而程序是相对长久的

一个程序可对应多个进程

进程具有创建其他进程的 功能

3、进程的地址空间

操作系统给每个进程都分配了一个地址空间

int myval;
int main( int argc, char *argv[] )
{
myval = atoi( argv[1] );
while ( 1 )
printf( “ myval is % d, loc 0x % lx \ n ”,
myval, (long) &myval );
}


同时 运行两个 Myval 程序,会输出什么?



输出的地址是相对地址 或者说是逻辑地址或者虚拟地址,所以才会出现变量不同,但地址相同的情况(因为两次运行是在不同的进程中的)。


4、上下文(CONTEXT)切换

将CPU 硬件状态从一个进程换到另一个进程的过程称为 上下文 切换

进程 运行时 ,其硬件状态保存在CPU 上 的寄存器中

寄存器:程序计数器、程序状态寄存器、栈指针、通用寄存器、其他控制寄存器的值

进程不运行时,这些寄存器的值保存在进程控制块

PCB 中; 当操作系统要 运行一个新的进程时,将PCB 中 的相关值 送到对应的寄存器 中

五、线程的引入

1、线程的开销小

创建 一个新线程花费时间少(撤销亦如此)

两 个 线程切换 花费时间少

线程 之间相互通信无须调用内核(同一进程内的线程共享内存和文件)



2、线程的属性

有标示符ID

有状态及状态转换 → 需要提供一些操作

不运行时需要保存的上下文

有上下文环境:程序计数器等寄存器

有自己的栈和栈指针 √

共享所在进程的地址空间和其他资源

可以创建、撤消另一个线程

程序开始是以一个单线程进程方式运行的

六、线程的实现机制

1、用户级线程



在用户空间建立 线程库:提供一组管理线程的过程

运行时系统:完成线程的 管理工作(操作、线程表)

内核管理的还是进程,不知道 线程的存在

线程 切换不 需要内核态特权

例子:UNIX

用户级线程小结:

优点:

线程切换快

调度算法是应用程序特定的

用户级线程可运行在任何操作系统上(只需要实现线程库)

缺点:

内核只将处理器分配给进程,同一进程中的两个线程不能同时运行于两个处理器上

大多数系统调用是阻塞的,因此,由于内核阻塞进程,故进程中所有线程也被阻塞

2、 核心级线程



内核管理所有线程管理,并向应用程序提供API接口

内核维护进程和线程的上下文

线程的切换需要内核支持

以线程为基础进行调度

例子:Windows

3、混合模型

线程创建在用户空间完成

线程调度等在核心态完成

例子:Solaris



4、可再入程序(可重入)

可被多个进程同时调用的程序,具有下列性质:
1、它是纯代码的,即在执行过程中自身不改变;
2、调用它的进程应该提供数据区


本文整理自:《操作系统原理》北京大学_陈向群 讲义

个人微信公众号:



作者:jiankunking 出处:http://blog.csdn.net/jiankunking
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息