选择
A
1、在执行主控制流程的某条指令时因为中断、异常或者系统调用进入内核。
2、内核处理完成,准备回到用户模式之前,先处理当前进程中可以递达的信号。如果信号的处理动作是自定义函数,则会回到用户态之后,再执行自定义处理函数。
3、信号处理函数返回时,执行特殊的系统调用(sigretum)再次进入内核。
4、sys_sigreturn() 返回用户模式,从上次被中断的地方继续往下执行。
虚拟存储就是进程的虚拟地址空间。
装入程序时,只将程序的一部分装入内存,而将其余部分留在外存,就可以启动程序执行。
虚拟存储采用连续分配方式,会使相当一部分内存空间都处于暂时或“永久”的空闲状态。造成内存资源的严重浪费,也无法从逻辑上扩大内存的容量,因此虚拟内容的实现只能建立在离散分配的内存管理的基础上。
虚拟存储器容量既不受外存容量限制,又不受内存容量限制。而是由CPU的寻址范围决定的。
系统调用。主程序中调用 pipe 或者 read等系统调用接口。然后又用户态切换为内核态。
外部中断。程序在运行的时候,ctrl+c 中断程序。
进程切换。进程的切换是由操作系统内核来调度产生的,在用户态是不会发生的。
缺页。访问某一块内存的时候,有可能导致缺页现象。
data section :代码段
共享:
文件描述符表
每种信号的处理方式
当前工作目录。
用户ID和组ID
不共享:
线程ID 处理器现场和栈指针 独立的栈空间 errno变量 信号屏蔽字 调度优先级
缺页中断产生后,需要在内存中找到空闲页框并分配给需要访问的页(可能涉及到页面置换)。
之后缺页中断处理程序调用设备驱动程序做磁盘IO,将位于外存上的页面调入内存。
调入后需要修改页表,将页表中代表该页是否在内存的标记位置1,并将物理页框号填入相应位置。
饥饿:
一直等待。
高响应比优先算法
当等待时间相同时,短进程的优先级高。
当需要运行时间相同时,作业的优先权又取决于等待时间,相当于先到先服务。
长作业的优先级可以随着等待时间的增加而增加,因此长作业等待一段时间后,仍可以被调度。
进程刚刚完成IO操作,刚进入就绪态等待被调度,此时降低他的优先级是不合理的。
进程持久处于就绪队列,一直没有被调度,此时更应该提高他的优先级。
进程刚开始运行就降低优先级,有可能会被其他进程抢断,也是不合理的。
活跃度:是指进程或者线程长时间得不到CPU占用。
在使用锁保证线程安全时可能会出现活跃度失败情况。主要包括饥饿、活锁、死锁。
活锁:
你让我,我让你,谁也不能用。
死锁:
我不让你,我拿着资源不释放。你也不让我,你也拿着资源不释放。
进程在运行期间通过fork(系统调用) 来创建多个新进程。每一个进程都有生命周期,即从创建到消亡的时间周期。当操作系统为一个程序构建一个进程控制块并分配地址空间之后,就创建了一个进程。进程的创建来源于:
1.提交一个批处理作业
2.在终端上一个交互式作业登录。
3.操作系统创建一个服务进程。
4.存在的进程创建新的进程。——fork
1.子进程有自己独立的虚拟地址空间。
2.每个线程都是独立被操作系统调度的,所有有独立的状态信息,改变主进程状态不会改变其他线程的状态。
3.父进程创建子进程时,子进程会复制父进程状态(包括锁),有可能导致子进程陷入死锁状态。
编程题
不用加号计算两个数相加
class UnusualAdd {
public:
int addAB(int A, int B)
{
if(A==0) return B;
if(B==0) return A;
unsigned int n1=A^B;//保存不进位的 相加之后的结果
unsigned int n2=A&B;//保存进位的值
n2<<=1;//进一位
return addAB(n1,n2);
}
};
三角形
#include<iostream>
using namespace std;
int main()
{
double a, b, c;
//这里我们规定a是最小值 b是较小值 c是最大值
while(cin>>a>>b>>c)
{
if(b<a) swap(a,b);
if(b>c) swap(b,c);
if(a + b > c)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}