使用户模式,电脑系统用户模式

CPU虚拟化就是对系统中的有限的物理CPU进行虚拟化,让系统中的多道程序都误认为自己占用了CPU资源。

CPU虚拟化的关键是对运行程序的抽象,即进程的概念,然后,系统需要保证多个进程可以独立的、不受干扰的运行,最后CPU如何调度这些进程,合理利用有限的CPU资源。

进程就是运行的程序,是程序在某一个数据集上的执行过程。

阻塞 状态也可以直接进入 运行 状态,这取决于系统的调度策略。

有了进程之后,我们可以让一个进程运行一段时间,然后切换另外一个进程运行一段时间,因为CPU的速度很快,所以看起来这些进程就像在同时运行一样。

现在的问题是,我们怎么样实现快速的进程切换,即 性能 问题。还有一个问题,操作系统必须拥有绝对的控制权,如何才能实现系统在执行用户程序的时候,操作系统还能重新获得CPU控制权呢?即 控制权 问题。

CPU存在两种模式(硬件支持): 用户模式 内核模式 。用户模式下运行的程序需要执行 陷阱 指令,才能进入内核模式。由于加入了硬件机制,此时操作系统可以掌控CPU。

时钟中断 ——操作系统打断正在运行的进程,获得CPU控制权。

中断发生时,硬件可以捕获到中断号,利用中断向量表(上图中的陷阱表),找到处理此中断的处理程序。

上下文切换:操作系统为当前正在执行的进程保存一些寄存器的值,并为即将执行的进程恢复一些寄存器的值。

请注意,在此协议中,有两种类型的寄存器保存/恢复。第一种是发生时钟中断的时候。在这种情况下,运行进程的用户寄存器由硬件隐式保存,使用该进程的 内核栈 。第二种是当操作系统决定从A切换到B。在这种情况下,内核寄存器被软件(即OS)明确地保存,但这次被存储在该进程的 进程结构的内存(进程控制块PCB) 中。后一个操作让系统从好像刚刚由A陷入内核,变成好像刚刚由B陷入内核。

Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

一个评价指标:周转时间——任务完成时间减去任务到达时间。

另外一个评价指标: 响应时间 ——从任务到达系统到首次运行的时间。 交互性。

1.编写一个调用fork()的程序。在调用fork()之前,让主进程访问一个变量(例如x)并将其值设置为某个值(例如100)。子进程中的变量有什么值?当子进程和父进程都改变x的值时,变量会发生什么?

2.编写一个打开文件的程序(使用open()系统调用),然后调用fork()创建一个新进程。子进程和父进程都可以访问open()返回的文件描述符吗?当它们并发(即同时)写入文件时,会发生什么?

3.使用fork()编写另一个程序。子进程应打印“hello”,父进程应打印“goodbye”。你应该尝试确保子进程始终先打印。你能否不在父进程调用wait()而做到这一点呢?

4.编写一个调用fork()的程序,然后调用某种形式的exec()来运行程序/bin/ls。看看是否可以尝试exec()的所有变体,包括execl()、execle()、execlp()、execv()、execvp()和execvP()。为什么同样的基本调用会有这么多变种?

5.现在编写一个程序,在父进程中使用wait(),等待子进程完成。wait()返回什么?如果你在子进程中使用wait()会发生什么?

6.对前一个程序稍作修改,这次使用waitpid()而不是wait()。什么时候waitpid()会有用?

7.编写一个创建子进程的程序,然后在子进程中关闭标准输出(STDOUT_FILENO)。如果子进程在关闭描述符后调用printf()打印输出,会发生什么?

8.编写一个程序,创建两个子进程,并使用pipe()系统调用,将一个子进程的标准输出连接到另一个子进程的标准输入。

1、管理员密码忘记了,重设一下密码就可以了。将Mac关机,然后重新开机,按下电源键的同时,立刻按住键盘上的command键+R键不要松手。

2、等待加载过去。

3、选择“以简体中文作为主要语言”。

4、点击下方的箭头继续。

5、点击屏幕顶端工具栏上的“实用工具”选项。

7、打开终端后,输入代码resetpassword,然后点回车。

8、点了回车后,终端界面后面会出现一个重设密码的界面。

9、选择你的管理员账户,然后点下一步。

10、进入设置密码界面,在“新密码”和“验证密码”中填入相同的新密码。

11、输入好新密码后点“下一步”。

12、看到界面提示“您的用户账户密码已重设。您可以重新启动并使用新密码来登录。”点击“重新启动”。

13、系统开始重启。

14、进入开机登录界面,输入刚才自己重设的新密码,然后登录。

15、登录后出现“系统无法将您的登录钥匙串解锁。”这里选择中间的选项“创建新钥匙串”。

16、登录进入系统桌面,管理员密码重设完成。