操作系统复习 第二章进程和线程

一.进程process

1.shell

操作系统其实是由多个功能模块组成的庞大、复杂的软件系统。在任何通用的操作系统中都需要去提供一个叫shell(外壳)的程序,我们就可以使用这个程序来操作计算机系统进行工作,其实我们所使用的可以在终端中输入命令,其实就是由命令行解释器进行解释运行的

在DOS中有一个程序叫做command.com,这个程序在DOS中被称为命令解释器,也就是DOS系统的shell。

DOS启动的时候,要先去完成一些系统的初始化工作,然后去运行command.com,当command.com运行之后,执行完一系列的相关任务之后,会在屏幕上显示出由当前的盘符和当前路径组成的提示符,比如说:“c:\” 或者是 “c:\windows 等”,然后光标闪烁,等待用户的输入

用户可以输入自己需要去执行的命令,比如说cd(切换到目录) 、ls(列出文件)、type(命令显示文本文件的内容),这些命令都是由command执行的,command执行完这些命令后,再次显示由当前盘符和当前路径组成的提示符,等待用户的输入。

当我们要执行一个程序的时候,我们要去输入该程序的可执行文件的名称,command首先会根据文件名去找到可执行文件,然后将这个可执行文件的程序加载进内存,然后去设置CS:IP指向程序的入口。此后command暂停运行,CPU运行程序。程序运行结束之后,要返回到command中,command再次显示由当前盘符和当前路径组成的提示符,等待用户的输入。

在DOS中,command处理各种输入:命令或者是要执行的程序的文件名其实就是通过command程序来工作的

2、fork()

一个程序一调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat,shmdt等)来操作。现在,已经是两个进程了,对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。

事实上,目前大多数的unix系统在实现上并没有作真正的copy。一般的,CPU都是以“页”为单位分配空间的,象INTEL的CPU,其一页在通常情况下是4K字节大小,而无论是数据段还是堆栈段都是由许多“页”构成的,fork函数复制这两个段,只是“逻辑”上的,并非“物理”上的,也就是说,实际执行fork时,物理空间上两个进程的数据段和堆栈段都还是共享着的,当有一个进程写了某个数据时,这时两个进程之间的数据才有了区
别,系统就将有区别的“页”从物理上也分开。系统在空间上的开销就可以达到最小。

3、对于exec系列函数

一个进程一旦调用exec类函数,它本身就“死亡”了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。不过exec类函数中有的还允许继承环境变量之类的信息,这个通过exec系列函数中的一部分函数的参数可以得到。

对于fork():
1、子进程复制父进程的所有进程内存到其内存地址空间中。父、子进程的
“数据段”,“堆栈段”和“代码段”完全相同,即子进程中的每一个字节都
和父进程一样。
2、子进程的当前工作目录、umask掩码值和父进程相同,fork()之前父进程
打开的文件描述符,在子进程中同样打开,并且都指向相同的文件表项。
3、子进程拥有自己的进程ID。

对于exec():
1、进程调用exec()后,将在同一块进程内存里用一个新程序来代替调用
exec()的那个进程,新程序代替当前进程映像,当前进程的“数据段”,
“堆栈段”和“代码段”背新程序改写。
2、新程序会保持调用exec()进程的ID不变。
3、调用exec()之前打开打开的描述字继续打开(好像有什么参数可以令打开
的描述字在新程序中关闭)

What is the difference between fork and exec? please use programs to prove your opinion.

答:Fork是创建一个新的进程(把进程原样复制一个新的出来),新进程和老进程相同只有进程号不同。但是exec用参数指定的程序代替当前进程的内容,也就是执行新的程序,它会将指定程序的代码段和数据段覆盖当前进程。

进程的三种基本状态

在这里插入图片描述

Process Creation 进程的创建

◦ System initialization. 系统初始化
◦ Execution of a process creation system call 正在运行的进程执行创建进程的系统调用
by a running process.
◦ A user request to create a new process. 用户请求创建一个新进程
◦ Initiation of a batch job 一个批处理作业的初始化

Process Termination 进程的终止

◦ Normal exit (voluntary). 正常终止
◦ Error exit (voluntary). 错误终止
◦ Fatal error (involuntary).严重错误 非自愿
◦ Killed by another process (involuntary) 被其他进程杀死

Process Internal Structure:

Code Segment; Data Segment;Stack; Address Space(Kernel SpaceKernel Mode; User Space User Mode),

process model

Feature: Multiprogramming— rapid
switching back and forth
多道程序设计 快速切换
在这里插入图片描述

Implementation of Process Model 进程模型的实现

PCB: Process Control Block 进程控制块 或者称为 process table

在这里插入图片描述
进程管理 内存管理 文件管理

进程切换

在这里插入图片描述
进程切换的步骤

在这里插入图片描述

Process Performance Measurement CPU利用率

◦ CPU utilization= 1-p^n p为等待I/O操作的时间与在内存中工作的时间之比

二.线程

在这里插入图片描述特点:lightweight process, multithreading 轻量级进程 多线程

Thread Usage

Why Thread?

The main reason for having threads is that in many
applications, multiple activities are going on at once. Some of these may block
from time to time. By decomposing
A second argument for having threads is that since they are lighter weight than
processes, they are easier (i.e., faster) to create and destroy than processes. In
many systems, creating a thread goes 10–100 times faster than creating a process.
When the number of threads needed changes dynamically and rapidly, this property is useful to have.
A third reason for having threads is also a performance argument. Threads
yield no performance gain when all of them are CPU bound, but when there is sub-stantial computing and also substantial I/O, having threads allows these activities to overlap, thus speeding up the application.
Finally, threads are useful on systems with multiple CPUs, where real paral-
lelism is possible.
在这里插入图片描述
在这里插入图片描述

Thread Internal Structure

Code; Data; Stack; Address Space; TCB
线程经典模型
在这里插入图片描述

Pop-Up Thread 弹出式线程

◦ In web server 在web服务器中
 The arrival of a message causes the system to create a
new thread to handle the message, such a thread is
called a pop-up thread

Why Pop-Up Thread?

 One reason: remove block
在这里插入图片描述

thread implementation

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进程和线程的联系和区别

定义:
一、进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。
二、线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程;

进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
(4)处理机分给线程,即真正在处理机上运行的是线程。
(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。
线程与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
(4) 系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后, 在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死 掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些。

线程的划分尺度小于进程,使得多线程程序的并发性高。

另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序运行效率。

线程在执行过程中,每个独立的线程有一个程序运行的入口,顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,有应用程序提供多个线程执行控制。

从逻辑角度看,多线程的意义子啊与一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

【同一进程间的线程共享的资源有】

a. 堆 由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)

b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的

c. 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的

d. 文件等公用资源 这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。

【独享的资源有】

a. 栈 栈是独享的 stack

b. 寄存器 这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC

线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。

【个性】进程拥有这许多共性的同时,还拥有自己的个性,才能实现并发性
1.线程ID
每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标识线程。

2.寄存器组的值
由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线程切换到另一个线程上 时,必须将原有的线程的寄存器集合的状态保存,以便将来该线程在被重新切换到时能得以恢复。

3.线程的堆栈
堆栈是保证线程独立运行所必须的。线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程必须拥有自己的函数堆栈, 使得函数调用可以正常执行,不受其他线程的影响。
4.错误返回码
由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用后设置了errno值,而在该 线程还没有处理这个错误,另外一个线程就在此时被调度器投入运行,这样错误值就有可能被修改。所以,不同的线程应该拥有自己的错误返回码变量。
5.线程的信号屏蔽码
由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理。但所有的线程都 共享同样的信号处理器。
6.线程的优先级
由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参数,这个参数就是线程的优先级。

IPC 进程间通信

concept: 例如一个进程的输出传给下个进程作为其输入
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.race condition 竞争条件

定义:Situations like this, where two or more processes are reading or writ-
ing some shared data and the final result depends on who runs precisely when, are
called race conditions 两个或多个进程读写某一共享文件,最终结果取决于其运行的精准时序

what we need is mutual exclusion 互斥

,that is, some way of making sure that if one process is using a shared
variable or file, the other processes will be excluded from doing the same thing. 确保共享文件被一个进程读取时其他进程被排斥在外

2.临界区 critical region

sometimes a process has to access shared memory or files, or do other critical things that can lead to races. That part of the program where the shared memory is accessed is called the critical
region or critical section
简而言之:可能产生竞争的代码区域

解决办法 good solution:
  1. No two processes may be simultaneously inside their critical regions.
  2. No assumptions may be made about speeds or the number of CPUs.
  3. No process running outside its critical region may block any process.
  4. No process should have to wait forever to enter its critical region.
    在这里插入图片描述
Spin lock 旋转锁
Mutual Exclusion with Busy Waiting 忙等待的互斥

1.屏蔽中断
2.锁变量 lock variables
3.严格轮换算法:
在这里插入图片描述
在这里插入图片描述

Sleep & Wake up 睡眠和唤醒

 Problem of busy waiting
◦ Waste CPU time.
◦ Cause Priority inversion Problem
 Sleep & Wakeup
◦ Key idea: Once find that it cannot enter
the critical region, the process will sleep. It
will be waked up by another process which
finish work in critical region and leave.

信号量Semaphores

在这里插入图片描述

mutex 互斥量

在这里插入图片描述

管程 Monitors

Monitors have an important property that makes them useful for achieving
mutual exclusion: only one process can be active in a monitor at any instant. Moni-
tors are a programming-language construct, so the compiler knows they are special
and can handle calls to monitor procedures differently from other procedure calls.
Typically, when a process calls a monitor procedure, the first few instructions of
the procedure will check to see if any other process is currently active within the
monitor. If so, the calling process will be suspended until the other process has left
the monitor. If no other process is using the monitor, the calling process may enter.
在这里插入图片描述

Barriers 屏障

在这里插入图片描述
在这里插入图片描述

生产者消费者问题

在这里插入图片描述

调度 SCHEDULING

Process States Transition 进程状态转换

Notice:for scheduling algorithm the key measurements :
turnaround time, response time, waiting time,mean turnaround time.
ii.FCFS先来先服务
iii.SJF(Notice: turn around time is optimal) 最短作业优先
iv.Round-Robin 轮转调度
v.Multiple Queue 多级调度

经典调度问题

1.哲学家就餐问题

在这里插入图片描述
如此永远重复下去,所有程序不停地运行,但都得不到进展,就称为饥饿(starvation)
改进算法:
在这里插入图片描述

2.读者写者问题

在这里插入图片描述

3.理发师问题

The Sleeping Barber(理发师) Problem is a classical IPC
problem.
◦ The barber shop has one barber, one barber chair, and n
chairs for waiting customers.
◦ If there are no customers present, the barber sits down in
the barber chair and falls asleep.
◦ When a customer arrives, he has to wake up the sleeping
barber.
◦ If additional customers arrive while the barber is cutting a
customer’s hair, they either sit down (if there are empty
chairs) or leave the shop (if all chairs are full)
在这里插入图片描述

4其他问题

在这里插入图片描述
在这里插入图片描述

系统调用

在这里插入图片描述

What is the difference between User Space and Kernel space?

答:应用程序正常情况下都是运行在普通模式下,这部分代码运行的空间称为用户空间,当代码通过系统调用计入到特权级别运行的时候,对应的代码执行空间称为内核空间。
内核态与用户态是操作系统的两种运行级别,当程序运行在3级特权级上时,就可以称之为运行在用户态,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当程序运行在0级特权级上时,就可以称之为运行在内核态。运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态。
处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理机是可被抢占的;而处于内核态执行的进程,则能访问所有的内存空间和对象,且所占有的处理机是不允许被抢占的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值