进程调度的算法

进程调度的算法,第1张

算法总是把处理机分配给最先进入就绪队列进程,一个进程一旦分得处理机,便一直执行下去,直到该进程完成或阻塞时,才释放处理机。

例如,有三个进程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进程、线程及调度算法(二)、进程调度算法 进程管理实验等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9307950.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存