算法总是把处理机分配给最先进入就绪队列的进程,一个进程一旦分得处理机,便一直执行下去,直到该进程完成或阻塞时,才释放处理机。
例如,有三个进程P1、P2和P3先后进入就绪队列,它们的执行期分别是21、6和3个单位时间,
执行情况如下图:
对于P1、P2、P3的周转时间为21、27、30,平均周转时间为26。
可见,FIFO算法服务质量不佳,容易引起作业用户不满,常作为一种辅助调度算法。 最短CPU运行期优先调度算法(SCBF--Shortest CPU Burst First)
该算法从就绪队列中选出下一个“CPU执行期最短”的进程,为之分配处理机。
例如,在就绪队列中有四个进程P1、P2、P3和P4,它们的下一个执行期分别是16、12、4和3个单位时间,执行情况如下图:
P1、P2、P3和P4的周转时间分别为35、19、7、3,平均周转时间为16。
该算法虽可获得较好的调度性能,但难以准确地知道下一个CPU执行期,而只能根据每一个进程的执行历史来预测。 前几种算法主要用于批处理系统中,不能作为分时系统中的主调度算法,在分时系统中,都采用时间片轮转法。
简单轮转法:系统将所有就绪进程按FIFO规则排队,按一定的时间间隔把处理机分配给队列中的进程。这样,就绪队列中所有进程均可获得一个时间片的处理机而运行。
多级队列方法:将系统中所有进程分成若干类,每类为一级。 多级反馈队列方式是在系统中设置多个就绪队列,并赋予各队列以不同的优先权。
执行一个 copy,但是只要任何修改,都造成分裂如,修改了chroot,写memory,mmap,sigaction 等。
p1 是一个 task_struct, p2 也是一个 task_struct linux内核的调度器只认得task_struck (不管你是进程还是线程), 对其进行调度。
p2 的task_struck 被创建出来后,也有一份自己的资源。但是这些资源会短暂的与p1 相同。
进程是区分资源的单位,你的资源是我的资源,那从概念上将就不叫进程。
其他资源都好分配,唯一比较难的是内存资源的重新分配。
非常简单的程序,但是可以充分说明 COW。
结果:10 -> 20 -> 10
COW 是严重依赖于CPU中的MMU。CPU如果没有 MMU,fork 是不能工作的。
在没有mmu的CPU中,不可能执行COW 的,所以只有vfork
vfork与fork相比的不同
P2没有自己的 task_struct, 也就是说P1 的内存资源 就是 P2的内存资源。
结果 10,20,20
vfork:
vfork 执行上述流程,P2也只是指向了P1的mm,那么将这个vfork 放大,其余的也全部clone,共同指向P1,那么就是线程的属性了。
phtread_create -> Clone()
P1 P2 在内核中都是 task_struct 都可以被调度。共享资源可调度,即线程。 这就是线程为什么也叫做轻量级进程
不需要太纠结线程和进程的区别。
4651 : TGID
4652, 4653 tid 内核中 task_struct 真正的pid
linux 总是白发人 送 黑发人。如果父进程在子进程推出前挂掉了。那么子进程应该怎么办?
p3 -> init, p5 -> subreaper
每一个孤儿都会找最近的火葬场
可以设置进程的属性,将其变为subreaper,会像1号进程那样收养孤儿进程。
linux的进程睡眠依靠等待队列,这样的机制类似与涉及模式中的订阅与发布。
睡眠,分两种
每一个进程都是创建出来的,那么第一个进程是谁创建的呢?
init 进程是被linux的 0 进程 创建出来的。开机创建。
父进程就是 0 号进程,但在pstree,是看不到0进程的。因为0进程创建子进程后,就退化成了idle进程。
idle进程是 linux内核里,特殊调度类。 所有进程都睡眠停止 ,则调度idle进程,进入到 wait for interrupte 等中断。此时 cpu及其省电,除非来一个中断,才能再次被唤醒。
唤醒后的任何进程,从调度的角度上说,都比idle进程地位高。idle是调度级别最最低的进程。
0 进程 一跑,则进入等中断。一旦其他进程被唤醒,就轮不到 0进程了。
所有进程都睡了,0就上来,则cpu需要进入省电模式
#include<stdioh>
#include<stdlibh>
#include<mathh>
int J=0,flag=0;
void process1()
{
if(flag!=1)
{
if(J==0)
{J=1;
flag=1;
printf("进程A可以使用临界资源\n");
return;
}
else
printf("临界资源忙进程A等待!\n");
}
else
{
J=0;
flag=0;
printf("进程A释放临界资源\n");
}
}
void process2()
{
if(flag!=2)
{
if(J==1) printf("临界资源忙进程B等待!\n");
else
{J=1;
flag=2;
printf("进程B可以使用临界资源\n");
return;
}
}
else
{
J=0;
flag=0;
printf("进程B释放临界资源\n");
}
}
void process3()
{
if(flag!=3)
{
if(J==1)
printf("临界资源忙进程C等待!\n");
else
{J=1;
flag=3;
printf("进程C可以使用临界资源\n");
return;
}
}
else
{
J=0;
flag=0;
printf("进程C释放临界资源\n");
}
}
void main()
{
int x,N,i;
printf("请输入循环次数N:\n");
scanf("%d",&N);
for(i=0;i<N;i++)
{
x=rand()%3+1;
if(x==1)
process1();
if(x==2)
process2();
if(x==3)
process3();
}
}
以上就是关于进程调度的算法全部的内容,包括:进程调度的算法、linux进程、线程及调度算法(二)、进程调度算法 进程管理实验等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)