c语言电梯调度算法
真不容易啊,怕是没人弄了!
优先级调度算法程序:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct node
{
char name[10]; /*进程标识符*/
int prio; /*进程优先数*/
int round; /*进程时间轮转时间片*/
int cputime; /*进程占用CPU时间*/
int needtime; /*进程到完成还要的时间*/
int count; /*计数器*/
char state; /*进程的状态*/
struct node *next; /*链指针*/
}PCB;
PCB *finish,*ready,*tail,*run; /*队列指针*/
int N; /*进程数*/
/*将就绪队列中的第一个进程投入运行*/
firstin()
{
run=ready; /*就绪队列头指针赋值给运行头指针*/
run->state='R'; /*进程状态变为运行态*/
ready=ready->next; /*就绪对列头指针后移到下一进程*/
}
/*标题输出函数*/
void prt1(char a)
{
if(toupper(a)=='P') /*优先数法*/
printf(" name cputime needtime priority state\n");
else
printf(" name cputime needtime count round state\n");
}
/*进程PCB输出*/
void prt2(char a,PCB *q)
{
if(toupper(a)=='P') /*优先数法的输出*/
printf(" %-10s%-10d%-10d%-10d %c\n",q->name,
q->cputime,q->needtime,q->prio,q->state);
else/*轮转法的输出*/
printf(" %-10s%-10d%-10d%-10d%-10d %-c\n",q->name,
q->cputime,q->needtime,q->count,q->round,q->state);
}
/*输出函数*/
void prt(char algo)
{
PCB *p;
prt1(algo); /*输出标题*/
if(run!=NULL) /*如果运行指针不空*/
prt2(algo,run); /*输出当前正在运行的PCB*/
p=ready; /*输出就绪队列PCB*/
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
p=finish; /*输出完成队列的PCB*/
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
getch(); /*压任意键继续*/
}
/*优先数的插入算法*/
insert1(PCB *q)
{
PCB *p1,*s,*r;
int b;
s=q; /*待插入的PCB指针*/
p1=ready; /*就绪队列头指针*/
r=p1; /*r做p1的前驱指针*/
b=1;
while((p1!=NULL)&&b) /*根据优先数确定插入位置*/
if(p1->prio>=s->prio)
{
r=p1;
p1=p1->next;
}
else
b=0;
if(r!=p1) /*如果条件成立说明插入在r与p1之间*/
{
r->next=s;
s->next=p1;
}
else
{
s->next=p1; /*否则插入在就绪队列的头*/
ready=s;
}
}
/*轮转法插入函数*/
insert2(PCB *p2)
{
tail->next=p2; /*将新的PCB插入在当前就绪队列的尾*/
tail=p2;
p2->next=NULL;
}
/*优先数创建初始PCB信息*/
void create1(char alg)
{
PCB *p;
int i,time;
char na[10];
ready=NULL; /*就绪队列头指针*/
finish=NULL; /*完成队列头指针*/
run=NULL; /*运行队列指针*/
printf("Enter name and time of process\n"); /*输入进程标识和所需时间创建PCB*/
for(i=1;i<=N;i++)
{
p=malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='w';
p->prio=50-time;
if(ready!=NULL) /*就绪队列不空调用插入函数插入*/
insert1(p);
else
{
p->next=ready; /*创建就绪队列的第一个PCB*/
ready=p;
}
}
clrscr();
printf(" output of priority:\n");
printf("************************************************\n");
prt(alg); /*输出进程PCB信息*/
run=ready; /*将就绪队列的第一个进程投入运行*/
ready=ready->next;
run->state='R';
}
/*轮转法创建进程PCB*/
void create2(char alg)
{
PCB *p;
int i,time;
char na[10];
ready=NULL;
finish=NULL;
run=NULL;
printf("Enter name and time of round process\n");
for(i=1;i<=N;i++)
{
p=malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->count=0; /*计数器*/
p->state='w';
p->round=2; /*时间片*/
if(ready!=NULL)
insert2(p);
else
{
p->next=ready;
ready=p;
tail=p;
}
}
clrscr();
printf(" output of round\n");
printf("************************************************\n");
prt(alg); /*输出进程PCB信息*/
run=ready; /*将就绪队列的第一个进程投入运行*/
ready=ready->next;
run->state='R';
}
/*优先数调度算法*/
priority(char alg)
{
while(run!=NULL) /*当运行队列不空时,有进程正在运行*/
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->prio=run->prio-3; /*每运行一次优先数降低3个单位*/
if(run->needtime==0) /*如所需时间为0将其插入完成队列*/
{
run->next=finish;
finish=run;
run->state='F'; /*置状态为完成态*/
run=NULL; /*运行队列头指针为空*/
if(ready!=NULL) /*如就绪队列不空*/
firstin(); /*将就绪对列的第一个进程投入运行*/
}
else /*没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列*/
if((ready!=NULL)&&(run->prio<ready->prio))
{
run->state='W';
insert1(run);
firstin(); /*将就绪队列的第一个进程投入运行*/
}
prt(alg); /*输出进程PCB信息*/
}
}
/*时间片轮转法*/
roundrun(char alg)
{
while(run!=NULL)
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->count=run->count+1;
if(run->needtime==0)/*运行完将其变为完成态,插入完成队列*/
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!=NULL)
firstin(); /*就绪对列不空,将第一个进程投入运行*/
}
else
if(run->count==run->round) /*如果时间片到*/
{
run->count=0; /*计数器置0*/
if(ready!=NULL) /*如就绪队列不空*/
{
run->state='W'; /*将进程插入到就绪队列中等待轮转*/
insert2(run);
firstin(); /*将就绪对列的第一个进程投入运行*/
}
}
prt(alg); /*输出进程信息*/
}
}
/*主函数*/
main()
{
char algo; /*算法标记*/
clrscr();
printf("type the algorithm:P/R(priority/roundrobin)\n");
scanf("%c",&algo); /*输入字符确定算法*/
printf("Enter process number\n");
scanf("%d",&N); /*输入进程数*/
if(algo=='P'||algo=='p')
{
create1(algo); /*优先数法*/
priority(algo);
}
else
if(algo=='R'||algo=='r')
{
create2(algo); /*轮转法*/
roundrun(algo);
}
}
‘贰’ 用C语言编写并调试一个模拟的进程调度程序,采用“简单时间片轮转法”调度算法对五个进程进行调度。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct PCB {
char NAME[10]; /*进程名*/
int ROUND; /*进程轮转时间片*/
int REACHTIME; /*进程到达时间*/
int CPUTIME; /*进程占用CPU时间*/
int COUNT; /*计数器*/
int NEEDTIME; /*进程完成还要的CPU时间*/
char STATE; /*进程的状态*/
struct PCB *NEXT; /*链指针*/
};
struct LINK { /*PCB的链结构*/
struct PCB *RUN; /*当前运行进程指针*/
struct PCB *READY; /*就绪队列头指针*/
struct PCB *TAIL; /*就绪队列尾指针*/
struct PCB *FINISH; /*完成队列头指针*/
};
void INIT(LINK *); /*对PCB的链结构初始化*/
void INSERT(LINK *); /*将执行了一个单位时间片数且还未完成的进程的PCB插到就绪队列的队尾*/
void FIRSTIN(LINK *); /*将就绪队列中的第一个进程投入运行*/
void PRINT(LINK *); /*打印每执行一个时间片后的所有进程的状态*/
void PR(PCB *); /*打印一个进程的状态*/
int CREATE(LINK *,int); /*创建新的进程*/
void ROUNDSCH(LINK *); /*按时间片轮转法调度进程*/
void main() {
LINK pcbs;
int i;
INIT(&pcbs);
i=0;
printf("创建5个进程\n\n");
while(i<5) {
if(CREATE(&pcbs,i+1)==1) {
printf("进程已创建\n\n");
i++;
}
else
printf("进程创建失败\n\n");
}
FIRSTIN(&pcbs);
ROUNDSCH(&pcbs);
}
void ROUNDSCH(LINK *p) {
PCB *pcb;
while(p->RUN!=NULL) {
pcb=(PCB *)malloc(sizeof(PCB));
strcpy(pcb->NAME,p->RUN->NAME);
pcb->ROUND=p->RUN->ROUND;
pcb->REACHTIME=p->RUN->REACHTIME;
pcb->CPUTIME=p->RUN->CPUTIME;
pcb->COUNT=p->RUN->COUNT;
pcb->NEEDTIME=p->RUN->NEEDTIME;
pcb->STATE=p->RUN->STATE;
pcb->NEXT=p->RUN->NEXT;
pcb->CPUTIME++;
pcb->NEEDTIME--;
pcb->COUNT++;
if(pcb->NEEDTIME==0) {
pcb->NEXT=p->FINISH->NEXT;
p->FINISH->NEXT=pcb;
pcb->STATE='F';
p->RUN=NULL;
if(p->READY!=p->TAIL)
FIRSTIN(p);
}
else {
p->RUN=pcb;
if(pcb->COUNT==pcb->ROUND) {
pcb->COUNT=0;
if(p->READY!=p->TAIL) {
pcb->STATE='W';
INSERT(p);
FIRSTIN(p);
}
}
}
PRINT(p);
}
}
void INIT(LINK *p) {
p->RUN=NULL;
p->TAIL=p->READY=(PCB *)malloc(sizeof(PCB));
p->READY->NEXT=NULL;
p->FINISH=(PCB *)malloc(sizeof(PCB));
p->FINISH->NEXT=NULL;
}
int CREATE(LINK *p,int n) {
PCB *pcb,*q;
pcb=(PCB *)malloc(sizeof(PCB));
flushall();
printf("请输入第%d个进程的名称:\n",n);
gets(pcb->NAME);
printf("请输入第%d个进程的轮转时间片数:\n",n);
scanf("%d",&(pcb->ROUND));
printf("请输入第%d个进程的到达时间:\n",n);
scanf("%d",&(pcb->REACHTIME));
pcb->CPUTIME=0;
pcb->COUNT=0;
printf("请输入第%d个进程需运行的时间片数:\n",n);
scanf("%d",&(pcb->NEEDTIME));
pcb->STATE='W';
pcb->NEXT=NULL;
if(strcmp(pcb->NAME,"")==0||pcb->ROUND<=0||pcb->NEEDTIME<=0) /*输入错误*/
return 0;
q=p->READY;
while(q->NEXT!=NULL&&q->NEXT->REACHTIME<=pcb->REACHTIME)
q=q->NEXT;
pcb->NEXT=q->NEXT;
q->NEXT=pcb;
if(pcb->NEXT==NULL)
p->TAIL=pcb;
return 1;
}
void FIRSTIN(LINK *p) {
PCB *q;
q=p->READY->NEXT;
p->READY->NEXT=q->NEXT;
q->NEXT=NULL;
if(p->READY->NEXT==NULL)
p->TAIL=p->READY;
q->STATE='R';
p->RUN=q;
}
void INSERT(LINK *p) {
PCB *pcb;
pcb=(PCB *)malloc(sizeof(PCB));
strcpy(pcb->NAME,p->RUN->NAME);
pcb->ROUND=p->RUN->ROUND;
pcb->REACHTIME=p->RUN->REACHTIME;
pcb->CPUTIME=p->RUN->CPUTIME;
pcb->COUNT=p->RUN->COUNT;
pcb->NEEDTIME=p->RUN->NEEDTIME;
pcb->STATE=p->RUN->STATE;
pcb->NEXT=p->RUN->NEXT;
p->TAIL->NEXT=pcb;
p->TAIL=pcb;
p->RUN=NULL;
pcb->STATE='W';
}
void PRINT(LINK *p) {
PCB *pcb;
printf("执行一个时间片后的所有进程的状态:\n\n");
if(p->RUN!=NULL)
PR(p->RUN);
if(p->READY!=p->TAIL) {
pcb=p->READY->NEXT;
while(pcb!=NULL) {
PR(pcb);
pcb=pcb->NEXT;
}
}
pcb=p->FINISH->NEXT;
while(pcb!=NULL) {
PR(pcb);
pcb=pcb->NEXT;
}
}
void PR(PCB *p) {
printf("进程名:%s\n",p->NAME);
printf("进程轮转时间片:%d\n",p->ROUND);
printf("进程到达时间:%d\n",p->REACHTIME);
printf("进程占用CPU时间:%d\n",p->CPUTIME);
printf("计数器:%d\n",p->COUNT);
printf("进程完成还要的CPU时间:%d\n",p->NEEDTIME);
printf("进程的状态:%c\n\n",p->STATE);
}
‘叁’ 求进程调度先来先服务算法,短进程优先算法完整c语言代码
/*(一)进程调度
进程调度算法有FIFO,优先数调度算法,时间片轮转调度算法,分级调度算法,
输入:进程流文件,其中存储的是一系列要执行的进程,
每个作业包括三个数据项:
进程名 所需时间 优先数(0级最高)
输出:
进程执行流 等待时间 平均等待时间
本程序包括:FIFO,优先数调度算法,时间片轮转调度算法
进程流文件process_stream.txt
测试数据:
p0 16 2
p1 5 1
p2 4 3
p3 8 0
p4 9 4
p5 7 6
VC++调试通过
*/
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <stdlib.h>
const int Quatum=2;//定义时间片的长度为2秒
const int MAXPCB=100;//定义最大进程数
//定义进程结构体
typedef struct node
{
char name[20];//进程名
int time; //进程运行时间
int privilege;//进程优先级(静态)
int finished;//进程完成标志,0-未完成,1-已完成
int wait_time;//进程等待时间
}pcb;
pcb pcbs[MAXPCB];
int quantiry;//进程流文件中的进程总数
void initial()
{
int i;
for (i=0;i<MAXPCB;i++)
{
strcpy(pcbs[i].name,"");
pcbs[i].time=0;
pcbs[i].privilege=0;
pcbs[i].finished=0;
pcbs[i].wait_time=0;
}
quantiry=0;
}
int readData()
{
FILE *fp;
char fname[20];
int i;
cout<<"请输入进程流文件名:"<<endl;
cin>>fname;
if ((fp=fopen(fname,"r"))==NULL)
{
cout<<"错误,文件打不开,请检查文件名"<<endl;
}
else
{
while (!feof(fp))
{
fscanf(fp,"%s %d %d %d",pcbs[quantiry].name,
&pcbs[quantiry].time,&pcbs[quantiry].privilege);
quantiry++;
}
//输出所读入得数据
cout<<"输出所读入的数据"<<endl;
cout<<"进程流文件中的进程总数="<<quantiry<<endl;
cout<<"进程名 所需时间 优先数"<<endl;
for (i=0;i<quantiry;i++)
{
cout<<" "<<pcbs[i].name<<" "<<pcbs[i].time<<" "<<pcbs[i].privilege<<endl;
}
return 1;
}
return 0;
}
//重置数据,以供另一个算法使用
void init()
{
int i;
for (i=0;i<MAXPCB;i++)
{
pcbs[i].finished=0;
pcbs[i].wait_time=0;
}
}
void FIFO()
{
int i,j;
int total;
//输出FIFO算法执行流
cout<<endl<<"---------------------------------------------------------------"<<endl;
cout<<"FIFO算法执行流:"<<endl;
cout<<"进程名 等待时间"<<endl;
for (i=0;i<quantiry;i++)
{
cout<<" "<<pcbs[i].name<<" "<<pcbs[i].wait_time<<endl;
for (j=i+1;j<quantiry;j++)
{
pcbs[j].wait_time+=pcbs[i].time;
}
}
total=0;
for (i=0;i<quantiry;i++)
{
total+=pcbs[i].wait_time;
}
cout<<"总等待时间:"<<total<<" "<<"平均等待时间:"<<total/quantiry<<endl;
}
//优先度调度算法
void privilege()
{
int i,j,p;
int passed_time=0;
int total;
int queue[MAXPCB];
int current_privielege=1000;
for (i=0;i<quantiry;i++)
{
current_privielege=1000;
for (j=0;j<quantiry;j++)
{
if ((pcbs[j].finished==0)&&(pcbs[j].privilege<current_privielege))
{
p=j;
current_privielege=pcbs[j].privilege;
}
}
queue[i]=p;
pcbs[p].finished=1;
pcbs[p].wait_time+=passed_time;
passed_time+=pcbs[p].time;
}
//输出优先数调度执行流
cout<<endl<<"-----------------------------------------"<<endl;
cout<<"优先数调度执行流:"<<endl;
cout<<"进程名 等待时间"<<endl;
for (i=0;i<quantiry;i++)
{
cout<<" "<<pcbs[queue[i]].name<<" "<<pcbs[queue[i]].wait_time<<"--"<<queue[i]<<endl;
}
total=0;
for (i=0;i<quantiry;i++)
{
total+=pcbs[i].wait_time;
}
cout<<"总等待时间:"<<total<<" 平均等待时间:"<<total/quantiry<<endl;
}
//时间片轮转调度算法
void timer()
{
int i,j,sum,flag=1;
int passed_time=0;
int max_time=0;
int round=0;
int queue[1000];
int total=0;
while(flag==1)
{
flag=0;
for (i=0;i<quantiry;i++)
{
if (pcbs[i].finished==0)
{
flag=1;
queue[total]=i;
total++;
if (pcbs[i].time<=Quatum*(round+1))
pcbs[i].finished=1;
}
}
round++;
}
cout<<endl<<"---------------------------------------------------------------"<<endl;
cout<<"时间片轮转调度执行流:";
for(i=0;i<total;i++)
{
cout<<pcbs[queue[i]].name<<" ";
}
cout<<endl;
cout<<"进程名 结束时间 运行时间 等待时间"<<endl;
sum=0;
for (i=0;i<quantiry;i++)
{
for(j=total-1;j>=0;j--)//从轮转调度执行流序列由后往前比较,找到同名进程即可计算其完成时间
{
if (strcmp(pcbs[queue[j]].name,pcbs[i].name)==0)
{
cout<<" "<<pcbs[i].name<<" "<<(j+1)*Quatum<<" ";
cout<<pcbs[i].time<<" "<<(j+1)*Quatum-pcbs[i].time<<endl;
sum+=(j+1)*Quatum-pcbs[i].time;
break;
}
}
}
cout<<"总等待时间:"<<sum<<" "<<"平均等待时间:"<<sum/quantiry<<endl;
}
//显示版权信息函数
void version()
{
cout<<endl<<endl;
cout<<" ┏━━━━━━━━━━━━━━━━━━━━━━━┓"<<endl;
cout<<" ┃ 进程调度模拟系统 ┃"<<endl;
cout<<" ┠───────────────────────┨"<<endl;
cout<<" ┃ version 2011 ┃"<<endl;
cout<<" ┗━━━━━━━━━━━━━━━━━━━━━━━┛"<<endl;
cout<<endl<<endl;
}
//主函数
int main()
{
int flag;
version();
initial();
flag=readData();
if(flag==1){
FIFO();
init();
privilege();
init();
timer();
}
cout<<endl;
system("pause");
return 0;
}
‘肆’ 濡备綍鎻愰珮Linux涓嫔潡璁惧呕O镄勬暣浣撴ц兘
鍓嶈█锛氭湰鏂囦富瑕佽茶ВLinux IO璋冨害灞傜殑涓夌嶆ā寮忥细cfp銆乨eadline鍜宯oop锛屽苟缁椤嚭钖勮嚜镄勪紭鍖栧拰阃傜敤鍦烘櫙寤鸿銆
IO璋冨害鍙戠敓鍦↙inux鍐呮牳镄処O璋冨害灞伞傝繖涓灞傛℃槸阍埚筁inux镄勬暣浣揑O灞傛′綋绯绘潵璇寸殑銆备粠read()鎴栬厀rite()绯荤粺璋幂敤镄勮掑害𨱒ヨ达纴Linux鏁翠綋IO浣撶郴鍙浠ュ垎涓轰竷灞傦纴瀹冧滑鍒嗗埆鏄锛
VFS灞傦细 铏氭嫙鏂囦欢绯荤粺灞伞傜敱浜庡唴镙歌佽窡澶氱嶆枃浠剁郴缁熸墦浜ら亾锛岃屾疮涓绉嶆枃浠剁郴缁熸墍瀹炵幇镄勬暟鎹缁撴瀯鍜岀浉鍏虫柟娉曢兘鍙鑳戒笉灏界浉钖岋纴镓浠ワ纴鍐呮牳鎶借薄浜呜繖涓灞傦纴涓挞棬鐢ㄦ潵阃傞厤钖勭嶆枃浠剁郴缁燂纴骞跺瑰栨彁渚涚粺涓镎崭綔鎺ュ彛銆
鏂囦欢绯荤粺灞傦细 涓嶅悓镄勬枃浠剁郴缁熷疄鐜拌嚜宸辩殑镎崭綔杩囩▼锛屾彁渚涜嚜宸辩壒链夌殑鐗瑰緛锛屽叿浣扑笉澶氲翠简锛屽ぇ瀹舵効镒忕殑璇濊嚜宸卞幓鐪嬩唬镰佸嵆鍙銆
椤电紦瀛桦眰锛 璐熻矗鐪熷筽age镄勭紦瀛樸
阃氱敤鍧楀眰锛 鐢变簬缁濆ぇ澶氭暟𨱍呭喌镄刬o镎崭綔鏄璺熷潡璁惧囨墦浜ら亾锛屾墍浠Linux鍦ㄦゆ彁渚涗简涓涓绫讳技vfs灞傜殑鍧楄惧囨搷浣沧娊璞″眰銆备笅灞傚规帴钖勭崭笉钖屽睘镐х殑鍧楄惧囷纴瀵逛笂鎻愪緵缁熶竴镄凚lock IO璇锋眰镙囧嗳銆
IO璋冨害灞 锛氩洜涓虹粷澶у氭暟镄勫潡璁惧囬兘鏄绫讳技纾佺洏杩欐牱镄勮惧囷纴镓浠ユ湁蹇呰佹牴鎹杩欑被璁惧囩殑鐗圭偣浠ュ强搴旂敤镄勪笉钖岀壒镣规潵璁剧疆涓浜涗笉钖岀殑璋冨害绠楁硶鍜岄槦鍒椼备互渚垮湪涓嶅悓镄勫簲鐢ㄧ幆澧冧笅链夐拡瀵规х殑鎻愰珮纾佺洏镄勮诲啓鏁堢巼锛岃繖閲屽氨鏄澶у悕榧庨紟镄凩inux鐢垫镓璧蜂綔鐢ㄧ殑鍦版柟銆傞拡瀵规満姊扮‖鐩樼殑钖勭嶈皟搴︽柟娉曞氨鏄鍦ㄨ繖瀹炵幇镄勚
鍧楄惧囬┍锷ㄥ眰锛 椹卞姩灞傚瑰栨彁渚涚浉瀵规瘆杈冮珮绾х殑璁惧囨搷浣沧帴鍙o纴寰寰鏄疌璇瑷镄勶纴钥屼笅灞傚规帴璁惧囨湰韬镄勬搷浣沧柟娉曞拰瑙勮寖銆
鍧楄惧囧眰锛 杩椤眰灏辨槸鍏蜂綋镄勭墿鐞呜惧囦简锛屽畾涔変简钖勭岖湡瀵硅惧囨搷浣沧柟娉曞拰瑙勮寖銆
链変竴涓宸茬粡鏁寸悊濂界殑[Linux IO缁撴瀯锲纶锛岄潪甯哥粡鍏革纴涓锲捐儨鍗冭█锛
鎴戜滑浠婂ぉ瑕佺爷绌剁殑鍐呭逛富瑕佸湪IO璋冨害杩欎竴灞伞
瀹冭佽В鍐崇殑镙稿绩闂棰樻槸锛屽备綍鎻愰珮鍧楄惧呕O镄勬暣浣撴ц兘锛熻繖涓灞备篃涓昏佹槸阍埚规満姊扮‖鐩樼粨鏋勮岃捐$殑銆
浼楁墍锻ㄧ煡锛屾満姊扮‖鐩樼殑瀛桦偍浠嬭川鏄纾佺洏锛岀佸ご鍦ㄧ洏鐗囦笂绉诲姩杩涜岀侀亾瀵诲潃锛岃屼负绫讳技鎾鏀句竴寮犲敱鐗囥
杩欑岖粨鏋勭殑鐗圭偣鏄锛岄‘搴忚块梾镞跺闷钖愰噺杈冮珮锛屼絾鏄濡傛灉涓镞﹀圭洏鐗囨湁闅忔満璁块梾锛岄偅涔埚ぇ閲忕殑镞堕棿閮戒细娴璐瑰湪纾佸ご镄勭Щ锷ㄤ笂锛岃繖镞跺椤氨浼氩艰嚧姣忔IO镄勫搷搴旀椂闂村彉闀匡纴鏋佸ぇ镄勯檷浣嶪O镄勫搷搴旈熷害銆
纾佸ご鍦ㄧ洏鐗囦笂瀵婚亾镄勬搷浣滐纴绫讳技鐢垫璋冨害锛屽疄闄呬笂鍦ㄦ渶寮濮嬬殑镞舵湡锛孡inux鎶婅繖涓绠楁硶锻藉悕涓篖inux鐢垫绠楁硶锛屽嵆锛
濡傛灉鍦ㄥ婚亾镄勮繃绋嬩腑锛岃兘鎶婇‘搴忚矾杩囩殑鐩稿叧纾侀亾镄勬暟鎹璇锋眰閮解滈‘渚库濆勭悊鎺夛纴闾d箞灏卞彲浠ュ湪姣旇缉灏忓奖鍝嶅搷搴旈熷害镄勫墠鎻愪笅锛屾彁楂樻暣浣揑O镄勫闷钖愰噺銆
杩椤氨鏄鎴戜滑涓轰粈涔堣佽捐IO璋冨害绠楁硶镄勫师锲犮
鐩鍓嶅湪鍐呮牳涓榛樿ゅ紑钖浜嗕笁绉岖畻娉/妯″纺锛歯oop锛宑fq鍜宒eadline銆备弗镙肩畻搴旇ユ槸涓ょ嶏细
锲犱负绗涓绉嶅彨锅歯oop锛屽氨鏄绌烘搷浣滆皟搴︾畻娉曪纴涔熷氨鏄娌℃湁浠讳綍璋冨害镎崭綔锛屽苟涓嶅筰o璇锋眰杩涜屾帓搴忥纴浠呬粎锅氶傚綋镄刬o钖埚苟镄勪竴涓猣ifo阒熷垪銆
鐩鍓嶅唴镙镐腑榛樿ょ殑璋冨害绠楁硶搴旇ユ槸cfq锛屽彨锅氩畬鍏ㄥ叕骞抽槦鍒楄皟搴︺傝繖涓璋冨害绠楁硶浜哄傚叾钖嶏纴瀹冭瘯锲剧粰镓链夎繘绋嬫彁渚涗竴涓瀹屽叏鍏骞崇殑IO镎崭綔鐜澧冦
娉锛氲峰ぇ瀹朵竴瀹氲颁綇杩欎釜璇嶈锛宑fq锛屽畬鍏ㄥ叕骞抽槦鍒楄皟搴︼纴涓岖劧涓嬫枃灏辨病娉旷湅浜嗐
cfq涓烘疮涓杩涚▼鍒涘缓涓涓钖屾IO璋冨害阒熷垪锛屽苟榛樿や互镞堕棿鐗囧拰璇锋眰鏁伴檺瀹氱殑鏂瑰纺鍒嗛厤IO璧勬簮锛屼互姝や缭璇佹疮涓杩涚▼镄処O璧勬簮鍗犵敤鏄鍏骞崇殑锛宑fq杩桦疄鐜颁简阍埚硅繘绋嬬骇鍒镄勪紭鍏堢骇璋冨害锛岃繖涓鎴戜滑钖庨溃浼氲︾粏瑙i喷銆
镆ョ湅鍜屼慨鏀笽O璋冨害绠楁硶镄勬柟娉曟槸锛
cfq鏄阃氱敤链嶅姟鍣ㄦ瘆杈冨ソ镄処O璋冨害绠楁硶阃夋嫨锛屽规岄溃鐢ㄦ埛涔熸槸姣旇缉濂界殑阃夋嫨銆
浣嗘槸瀵逛簬寰埚欼O铡嫔姏杈冨ぇ镄勫満鏅灏卞苟涓嶆槸寰堥傚簲锛屽挨鍏舵槸IO铡嫔姏闆嗕腑鍦ㄦ煇浜涜繘绋嬩笂镄勫満鏅銆
锲犱负杩欑嶅満鏅鎴戜滑闇瑕佹洿澶氱殑婊¤冻镆愪釜鎴栬呮煇鍑犱釜杩涚▼镄処O鍝嶅簲阃熷害锛岃屼笉鏄璁╂墍链夌殑杩涚▼鍏骞崇殑浣跨敤IO锛屾瘆濡傛暟鎹搴揿簲鐢ㄣ
deadline璋冨害锛堟渶缁堟湡闄愯皟搴︼级灏辨槸镟撮傚悎涓婅堪鍦烘櫙镄勮В鍐虫柟妗堛俤eadline瀹炵幇浜嗗洓涓阒熷垪锛
鍏朵腑涓や釜鍒嗗埆澶勭悊姝e父read鍜寃rite锛屾寜镓囧尯鍙锋帓搴忥纴杩涜屾e父io镄勫悎骞跺勭悊浠ユ彁楂桦闷钖愰噺銆傚洜涓篒O璇锋眰鍙鑳戒细闆嗕腑鍦ㄦ煇浜涚佺洏浣岖疆锛岃繖镙蜂细瀵艰嚧鏂版潵镄勮锋眰涓鐩磋钖埚苟锛屽彲鑳戒细链夊叾浠栫佺洏浣岖疆镄刬o璇锋眰琚楗挎汇
鍙﹀栦袱涓澶勭悊瓒呮椂read鍜寃rite镄勯槦鍒楋纴鎸夎锋眰鍒涘缓镞堕棿鎺掑簭锛屽傛灉链夎秴镞剁殑璇锋眰鍑虹幇锛屽氨鏀捐繘杩欎袱涓阒熷垪锛岃皟搴︾畻娉曚缭璇佽秴镞讹纸杈惧埌链缁堟湡闄愭椂闂达级镄勯槦鍒椾腑镄勮锋眰浼氢紭鍏堣澶勭悊锛岄槻姝㈣锋眰琚楗挎汇
涓崭箙鍓嶏纴鍐呮牳杩樻槸榛樿ゆ爣閰嶅洓绉岖畻娉曪纴杩樻湁涓绉嶅彨锅歛s镄勭畻娉曪纸Anticipatory scheler锛夛纴棰勬祴璋冨害绠楁硶銆备竴涓楂桦ぇ涓婄殑钖嶅瓧锛屾闷寰楁垜涓搴﹁や负Linux鍐呮牳閮戒细绠楀懡浜嗐
缁撴灉鍙戠幇锛屾棤闱炴槸鍦ㄥ熀浜巇eadline绠楁硶锅歩o璋冨害镄勪箣鍓岖瓑涓灏忎细镞堕棿锛屽傛灉杩欐垫椂闂村唴链夊彲浠ュ悎骞剁殑io璇锋眰鍒版潵锛屽氨鍙浠ュ悎骞跺勭悊锛屾彁楂榙eadline璋冨害镄勫湪椤哄簭璇诲啓𨱍呭喌涓嬬殑鏁版嵁钖炲悙閲忋
鍏跺疄杩欐牴链涓嶆槸鍟ラ勬祴锛屾垜瑙夊缑涓嶅傚彨鎾炲ぇ杩愯皟搴︾畻娉曪纴褰撶劧杩欑岖瓥鐣ュ湪镆愪簺鐗瑰畾鍦烘櫙宸鏁堟灉涓嶉敊銆
浣嗘槸鍦ㄥぇ澶氭暟鍦烘櫙涓嬶纴杩欎釜璋冨害涓崭粎娌℃湁鎻愰珮钖炲悙閲忥纴杩橀檷浣庝简鍝嶅簲阃熷害锛屾墍浠ュ唴镙稿共鑴嗘妸瀹冧粠榛樿ら厤缃閲屽垹闄や简銆傛瘯绔烲inux镄勫畻镞ㄦ槸瀹炵敤锛岃屾垜浠涔熷氨涓嶅啀杩欎釜璋冨害绠楁硶涓婂氲垂鍙h垖浜嗐
1銆乧fq锛氩畬鍏ㄥ叕骞抽槦鍒楄皟搴
cfq鏄鍐呮牳榛樿ら夋嫨镄処O璋冨害阒熷垪锛屽畠鍦ㄦ岄溃搴旂敤鍦烘櫙浠ュ强澶у氭暟甯歌佸簲鐢ㄥ満鏅涓嬮兘鏄寰埚ソ镄勯夋嫨銆
濡备綍瀹炵幇涓涓镓璋撶殑瀹屽叏鍏骞抽槦鍒楋纸Completely Fair Queueing锛夛纻
棣栧厛鎴戜滑瑕佺悊瑙f墍璋撶殑鍏骞虫槸瀵硅皝镄勫叕骞筹纻浠庢搷浣灭郴缁熺殑瑙掑害𨱒ヨ达纴浜х敓镎崭綔琛屼负镄勪富浣挞兘鏄杩涚▼锛屾墍浠ヨ繖閲岀殑鍏骞虫槸阍埚规疮涓杩涚▼钥岃█镄勶纴鎴戜滑瑕佽瘯锲捐╄繘绋嫔彲浠ュ叕骞崇殑鍗犵敤IO璧勬簮銆
闾d箞濡备綍璁╄繘绋嫔叕骞崇殑鍗犵敤IO璧勬簮锛熸垜浠闇瑕佸厛鐞呜В浠涔堟槸IO璧勬簮銆傚綋鎴戜滑琛¢噺涓涓狪O璧勬簮镄勬椂鍊欙纴涓鑸锽沧㈢敤镄勬槸涓や釜鍗曚綅锛屼竴涓鏄鏁版嵁璇诲啓镄勫甫瀹斤纴鍙︿竴涓鏄鏁版嵁璇诲啓镄処OPS銆
甯﹀藉氨鏄浠ユ椂闂翠负鍗曚綅镄勮诲啓鏁版嵁閲忥纴姣斿傦纴100Mbyte/s銆傝孖OPS鏄浠ユ椂闂翠负鍗曚綅镄勮诲啓娆℃暟銆傚湪涓嶅悓镄勮诲啓𨱍呭冧笅锛岃繖涓や釜鍗曚綅镄勮〃鐜板彲鑳戒笉涓镙凤纴浣嗘槸鍙浠ョ‘瀹氱殑鏄锛屼袱涓鍗曚綅镄勪换浣曚竴涓杈惧埌浜嗘ц兘涓婇檺锛岄兘浼氭垚涓篒O镄勭摱棰堛
浠庢満姊扮‖鐩樼殑缁撴瀯钥冭槛锛屽傛灉璇诲啓鏄椤哄簭璇诲啓锛岄偅涔圛O镄勮〃鐜版槸鍙浠ラ氲繃姣旇缉灏戠殑IOPS杈惧埌杈冨ぇ镄勫甫瀹斤纴锲犱负鍙浠ュ悎骞跺緢澶欼O锛屼篃鍙浠ラ氲繃棰勮荤瓑鏂瑰纺锷犻熸暟鎹璇诲彇鏁堢巼銆
褰揑O镄勮〃鐜版槸锅忓悜浜庨殢链鸿诲啓镄勬椂鍊欙纴闾d箞IOPS灏变细鍙桦缑镟村ぇ锛孖O镄勮锋眰镄勫悎骞跺彲鑳芥т笅闄嶏纴褰撴疮娆io璇锋眰鏁版嵁瓒婂皯镄勬椂鍊欙纴甯﹀借〃鐜板氨浼氲秺浣庛
浠庤繖閲屾垜浠鍙浠ョ悊瑙o纴阍埚硅繘绋嬬殑IO璧勬簮镄勪富瑕佽〃鐜板舰寮忔湁涓や釜锛 杩涚▼鍦ㄥ崟浣嶆椂闂村唴鎻愪氦镄処O璇锋眰涓鏁板拰杩涚▼鍗犵敤IO镄勫甫瀹姐
鍏跺疄镞犺哄摢涓锛岄兘鏄璺熻繘绋嫔垎閰岖殑IO澶勭悊镞堕棿闀垮害绱у瘑鐩稿叧镄勚
链夋椂涓氩姟鍙浠ュ湪杈冨皯IOPS镄勬儏鍐典笅鍗犵敤杈冨ぇ甯﹀斤纴鍙﹀栦竴浜涘垯鍙鑳藉湪杈冨ぇIOPS镄勬儏鍐典笅鍗犵敤杈冨皯甯﹀斤纴镓浠ュ硅繘绋嫔崰鐢↖O镄勬椂闂磋繘琛岃皟搴︽墠鏄鐩稿规渶鍏骞崇殑銆
鍗筹纴鎴戜笉绠′綘鏄疘OPS楂樿缮鏄甯﹀藉崰鐢ㄩ珮锛屽埌浜嗘椂闂村挶灏辨崲涓嬩竴涓杩涚▼澶勭悊锛屼綘鐖卞拫镙峰拫镙枫
镓浠ワ纴cfq灏辨槸璇曞浘缁欐墍链夎繘绋嫔垎閰岖瓑钖岀殑鍧楄惧囦娇鐢ㄧ殑镞堕棿鐗囷纴杩涚▼鍦ㄦ椂闂寸墖鍐咃纴鍙浠ュ皢浜х敓镄処O璇锋眰鎻愪氦缁椤潡璁惧囱繘琛屽勭悊锛屾椂闂寸墖缁撴潫锛岃繘绋嬬殑璇锋眰灏嗘帓杩涘畠镊宸辩殑阒熷垪锛岀瓑寰呬笅娆¤皟搴︾殑镞跺栾繘琛屽勭悊銆傝繖灏辨槸cfq镄勫熀链铡熺悊銆
褰撶劧锛岀幇瀹炵敓娲讳腑涓嶅彲鑳芥湁鐪熸g殑钬滃叕骞斥濓纴甯歌佺殑搴旂敤鍦烘櫙涓嬶纴鎴戜滑寰堣偗鑳介渶瑕佷汉涓虹殑瀵硅繘绋嬬殑IO鍗犵敤杩涜屼汉涓烘寚瀹氢紭鍏堢骇锛岃繖灏卞儚瀵硅繘绋嬬殑CPU鍗犵敤璁剧疆浼桦厛绾х殑姒傚康涓镙枫
镓浠ワ纴闄や简阍埚规椂闂寸墖杩涜屽叕骞抽槦鍒楄皟搴﹀栵纴cfq杩樻彁渚涗简浼桦厛绾ф敮鎸併傛疮涓杩涚▼閮藉彲浠ヨ剧疆涓涓狪O浼桦厛绾э纴cfq浼氭牴鎹杩欎釜浼桦厛绾х殑璁剧疆𨱍呭喌浣滀负璋冨害镞剁殑閲嶈佸弬钥冨洜绱犮
浼桦厛绾ч栧厛鍒嗘垚涓夊ぇ绫伙细RT銆丅E銆両DLE锛屽畠浠鍒嗗埆鏄瀹炴椂锛圧eal Time锛夈佹渶浣虫晥鏋滐纸Best Try锛夊拰闂茬疆锛圛dle锛変笁涓绫诲埆锛屽规疮涓绫诲埆镄処O锛宑fq閮戒娇鐢ㄤ笉钖岀殑绛栫暐杩涜屽勭悊銆傚彟澶栵纴RT鍜孊E绫诲埆涓锛屽垎鍒鍙埚啀鍒掑垎浜8涓瀛愪紭鍏堢骇瀹炵幇镟寸粏鑺傜殑QOS闇姹傦纴钥孖DLE鍙链変竴涓瀛愪紭鍏堢骇銆
鍙﹀栵纴鎴戜滑閮界煡阆揿唴镙搁粯璁ゅ瑰瓨鍌ㄧ殑璇诲啓閮芥槸缁忚繃缂揿瓨锛坆uffer/cache锛夌殑锛屽湪杩欑嶆儏鍐典笅锛宑fq鏄镞犳硶鍖哄垎褰揿墠澶勭悊镄勮锋眰鏄𨱒ヨ嚜鍝涓涓杩涚▼镄勚
鍙链夊湪杩涚▼浣跨敤钖屾ユ柟寮忥纸sync read鎴栬却ync wirte锛夋垨钥呯洿鎺IO锛图irect IO锛夋柟寮忚繘琛岃诲啓镄勬椂鍊欙纴cfq镓嶈兘鍖哄垎鍑篒O璇锋眰𨱒ヨ嚜鍝涓杩涚▼銆
镓浠ワ纴闄や简阍埚规疮涓杩涚▼瀹炵幇镄処O阒熷垪浠ュ栵纴杩桦疄鐜颁简涓涓鍏鍏辩殑阒熷垪鐢ㄦ潵澶勭悊寮傛ヨ锋眰銆
褰揿墠鍐呮牳宸茬粡瀹炵幇浜嗛拡瀵笽O璧勬簮镄刢group璧勬簮闅旂伙纴镓浠ュ湪浠ヤ笂浣撶郴镄勫熀纭涓婏纴cfq涔熷疄鐜颁简阍埚筩group镄勮皟搴︽敮鎸併
镐荤殑𨱒ヨ达纴cfq鐢ㄤ简涓绯诲垪镄勬暟鎹缁撴瀯瀹炵幇浜嗕互涓婃墍链夊嶆潅锷熻兘镄勬敮鎸侊纴澶у跺彲浠ラ氲繃婧愪唬镰佺湅鍒板叾鐩稿叧瀹炵幇锛屾枃浠跺湪婧愪唬镰佺洰褰曚笅镄刡lock/cfq-iosched.c銆
1.1 cfq璁捐″师鐞
鍦ㄦわ纴鎴戜滑瀵规暣浣撴暟鎹缁撴瀯锅氢竴涓绠瑕佹弿杩帮细棣栧厛锛宑fq阃氲繃涓涓鍙锅歝fq_data镄勬暟鎹缁撴瀯缁存姢浜嗘暣涓璋冨害鍣ㄦ祦绋嬨傚湪涓涓鏀鎸佷简cgroup锷熻兘镄刢fq涓锛屽叏閮ㄨ繘绋嬭鍒嗘垚浜呜嫢骞蹭釜contral group杩涜岀$悊銆
姣忎釜cgroup鍦╟fq涓閮芥湁涓涓猚fq_group镄勭粨鏋勮繘琛屾弿杩帮纴镓链夌殑cgroup閮借浣滀负涓涓璋冨害瀵硅薄鏀捐繘涓涓绾㈤粦镙戜腑锛屽苟浠vdisktime涓簁ey杩涜屾帓搴忋
vdisktime杩欎釜镞堕棿绾褰旷殑鏄褰揿墠cgroup镓鍗犵敤镄刬o镞堕棿锛屾疮娆″筩group杩涜岃皟搴︽椂锛屾绘槸阃氲繃绾㈤粦镙戦夋嫨褰揿墠vdisktime镞堕棿链灏戠殑cgroup杩涜屽勭悊锛屼互淇濊瘉镓链塩groups涔嬮棿镄処O璧勬簮鍗犵敤钬滃叕骞斥濄
褰撶劧鎴戜滑鐭ラ亾锛宑group鏄鍙浠ュ筨lkio杩涜岃祫婧愭瘆渚嫔垎閰岖殑锛屽叾浣灭敤铡熺悊灏辨槸锛屽垎閰嶆瘆渚嫔ぇ镄刢group鍗犵敤vdisktime镞堕棿澧为暱杈冩参锛屽垎閰嶆瘆渚嫔皬镄剉disktime镞堕棿澧为暱杈冨揩锛屽揩鎱涓庡垎閰嶆瘆渚嬫垚姝f瘆銆
杩欐牱灏卞仛鍒颁简涓嶅悓镄刢group鍒嗛厤镄処O姣斾緥涓崭竴镙凤纴骞朵笖鍦╟fq镄勮掑害鐪嬫潵渚濈劧鏄钬滃叕骞斥灭殑銆
阃夋嫨濂戒简闇瑕佸勭悊镄刢group锛坈fq_group锛変箣钖庯纴璋冨害鍣ㄩ渶瑕佸喅绛栭夋嫨涓嬩竴姝ョ殑service_tree銆
service_tree杩欎釜鏁版嵁缁撴瀯瀵瑰簲镄勯兘鏄涓绯诲垪镄勭孩榛戞爲锛屼富瑕佺洰镄勬槸鐢ㄦ潵瀹炵幇璇锋眰浼桦厛绾у垎绫荤殑锛屽氨鏄疪T銆丅E銆両DLE镄勫垎绫汇傛疮涓涓猚fq_group閮界淮鎶や简7涓狲ervice_trees锛屽叾瀹氢箟濡备笅锛
鍏朵腑service_tree_idle灏辨槸鐢ㄦ潵缁橧DLE绫诲瀷镄勮锋眰杩涜屾帓阒熺敤镄勭孩榛戞爲銆
钥屼笂闱浜岀淮鏁扮粍锛岄栧厛绗涓涓缁村害阍埚筊T鍜孊E鍒嗗埆钖勫疄鐜颁简涓涓鏁扮粍锛屾疮涓涓鏁扮粍涓閮界淮鎶や简涓変釜绾㈤粦镙戯纴鍒嗗埆瀵瑰簲涓夌崭笉钖屽瓙绫诲瀷镄勮锋眰锛屽垎鍒鏄锛歋YNC銆丼YNC_NOIDLE浠ュ强ASYNC銆
鎴戜滑鍙浠ヨや负SYNC鐩稿綋浜岙YNC_IDLE骞朵笌SYNC_NOIDLE瀵瑰簲銆俰dling鏄痗fq鍦ㄨ捐′笂涓轰简灏介噺钖埚苟杩炵画镄処O璇锋眰浠ヨ揪鍒版彁楂桦闷钖愰噺镄勭洰镄勮屽姞鍏ョ殑链哄埗锛屾垜浠鍙浠ョ悊瑙d负鏄涓绉嵝灭┖杞钬濈瓑寰呮満鍒躲
绌鸿浆鏄鎸囷纴褰扑竴涓阒熷垪澶勭悊涓涓璇锋眰缁撴潫钖庯纴浼氩湪鍙戠敓璋冨害涔嫔墠绌虹瓑涓灏忎细镞堕棿锛屽傛灉涓嬩竴涓璇锋眰鍒版潵锛屽垯鍙浠ュ噺灏戠佸ご瀵诲潃锛岀户缁澶勭悊椤哄簭镄処O璇锋眰銆
涓轰简瀹炵幇杩欎釜锷熻兘锛宑fq鍦╯ervice_tree杩椤眰鏁版嵁缁撴瀯杩椤疄鐜颁简SYNC阒熷垪锛屽傛灉璇锋眰鏄钖屾ラ‘搴忚锋眰锛屽氨鍏ラ槦杩欎釜service tree锛屽傛灉璇锋眰鏄钖屾ラ殢链鸿锋眰锛屽垯鍏ラ槦SYNC_NOIDLE阒熷垪锛屼互鍒ゆ柇涓嬩竴涓璇锋眰鏄钖︽槸椤哄簭璇锋眰銆
镓链夌殑寮傛ュ啓镎崭綔璇锋眰灏嗗叆阒烝SYNC镄剆ervice tree锛屽苟涓旈拡瀵硅繖涓阒熷垪娌℃湁绌鸿浆绛夊緟链哄埗銆
姝ゅ栵纴cfq杩桦笋SD杩欐牱镄勭‖鐩樻湁鐗规畩璋冩暣锛屽綋cfq鍙戠幇瀛桦偍璁惧囨槸涓涓狲sd纭鐩樿繖镙风殑阒熷垪娣卞害镟村ぇ镄勮惧囨椂锛屾墍链夐拡瀵瑰崟镫阒熷垪镄勭┖杞閮藉皢涓岖敓鏁堬纴镓链夌殑IO璇锋眰閮藉皢鍏ラ槦SYNC_NOIDLE杩欎釜service tree銆
姣忎竴涓狲ervice tree閮藉瑰簲浜呜嫢骞蹭釜cfq_queue阒熷垪锛屾疮涓猚fq_queue阒熷垪瀵瑰簲涓涓杩涚▼锛岃繖涓鎴戜滑钖庣画鍐嶈︾粏璇存槑銆
cfq_group杩樼淮鎶や简涓涓鍦╟group鍐呴儴镓链夎繘绋嫔叕鐢ㄧ殑寮傛IO璇锋眰阒熷垪锛屽叾缁撴瀯濡备笅锛
寮傛ヨ锋眰涔熷垎鎴愪简RT銆丅E銆両DLE杩欎笁绫昏繘琛屽勭悊锛屾疮涓绫诲瑰簲涓涓猚fq_queue杩涜屾帓阒熴
BE鍜孯T涔熷疄鐜颁简浼桦厛绾х殑鏀鎸侊纴姣忎竴涓绫诲瀷链塈OPRIO_BE_NR杩欎箞澶氢釜浼桦厛绾э纴杩欎釜鍊煎畾涔変负8锛屾暟缁勪笅镙囦负0-7銆
鎴戜滑鐩鍓嶅垎鏋愮殑鍐呮牳浠g爜鐗堟湰涓篖inux 4.4锛屽彲浠ョ湅鍑猴纴浠巆fq镄勮掑害𨱒ヨ达纴宸茬粡鍙浠ュ疄鐜板纾姝IO镄刢group鏀鎸佷简锛屾垜浠闇瑕佸畾涔変竴涓嬭繖閲屾墍璋揿纾姝IO镄勫惈涔夛纴瀹冧粎浠呰〃绀轰粠鍐呭瓨镄刡uffer/cache涓镄勬暟鎹钖屾ュ埌纭鐩樼殑IO璇锋眰锛岃屼笉鏄痑io(man 7 aio)鎴栬卨inux镄刵ative寮傛io浠ュ强lio链哄埗锛屽疄闄呬笂杩欎簺镓璋撶殑钬滃纾姝モ浐O链哄埗锛屽湪鍐呮牳涓閮芥槸钖屾ュ疄鐜扮殑锛堟湰璐ㄤ笂鍐璇轰纷镟艰$畻链烘病链夌湡姝g殑钬滃纾姝モ濇満鍒讹级銆
鎴戜滑鍦ㄤ笂闱㈠凡缁忚存槑杩囷纴鐢变簬杩涚▼姝e父𨱍呭喌涓嬮兘鏄灏嗘暟鎹鍏埚啓鍏buffer/cache锛屾墍浠ヨ繖绉嶅纾姝IO閮芥槸缁熶竴鐢眂fq_group涓镄刟sync璇锋眰阒熷垪澶勭悊镄勚
闾d箞涓轰粈涔埚湪涓婇溃镄剆ervice_tree涓杩樿佸疄鐜板拰涓涓狝SYNC镄勭被鍨嫔憿锛
杩椤綋铹舵槸涓轰简鏀鎸佸尯鍒呜繘绋嬬殑寮傛IO骞朵娇涔嫔彲浠モ滃畬鍏ㄥ叕骞斥濆仛鍑嗗囧柦銆
瀹为檯涓婂湪链鏂扮殑cgroup v2镄刡lkio浣撶郴涓锛屽唴镙稿凡缁忔敮鎸佷简阍埚筨uffer IO镄刢group闄愰熸敮鎸侊纴钥屼互涓婅繖浜涘彲鑳藉规槗娣锋穯镄勪竴鍫嗙被鍨嬶纴閮芥槸鍦ㄦ柊镄勪綋绯讳笅闇瑕佺敤鍒扮殑绫诲瀷镙囱般
鏂颁綋绯荤殑澶嶆潅搴︽洿楂树简锛屽姛鑳戒篃镟村姞寮哄ぇ锛屼絾鏄澶у跺厛涓嶈佺潃镐ワ纴姝e纺镄刢group v2浣撶郴锛屽湪Linux 4.5鍙戝竷镄勬椂鍊欎细姝e纺璺熷ぇ瀹惰侀溃銆
鎴戜滑缁х画阃夋嫨service_tree镄勮繃绋嬶纴涓夌崭紭鍏堢骇绫诲瀷镄剆ervice_tree镄勯夋嫨灏辨槸镙规嵁绫诲瀷镄勪紭鍏堢骇𨱒ュ仛阃夋嫨镄勶纴RT浼桦厛绾ф渶楂桡纴BE鍏舵★纴IDLE链浣庛傚氨鏄璇达纴RT閲屾湁锛屽氨浼氢竴鐩村勭悊RT锛孯T娌′简鍐嶅勭悊BE銆
姣忎釜service_tree瀵瑰簲涓涓鍏幂礌涓篶fq_queue鎺挜槦镄勭孩榛戞爲锛岃屾疮涓猚fq_queue灏辨槸鍐呮牳涓鸿繘绋嬶纸绾跨▼锛夊垱寤虹殑璇锋眰阒熷垪銆
姣忎竴涓猚fq_queue閮戒细缁存姢涓涓猺b_key镄勫彉閲忥纴杩欎釜鍙橀噺瀹为檯涓婂氨鏄杩欎釜阒熷垪镄処O链嶅姟镞堕棿锛坰ervice time锛夈
杩欓噷杩樻槸阃氲繃绾㈤粦镙戞垒鍒皊ervice time镞堕棿链鐭镄勯偅涓猚fq_queue杩涜屾湇锷★纴浠ヤ缭璇佲滃畬鍏ㄥ叕骞斥濄
阃夋嫨濂戒简cfq_queue涔嫔悗锛屽氨瑕佸紑濮嫔勭悊杩欎釜阒熷垪閲岀殑IO璇锋眰浜嗐傝繖閲岀殑璋冨害鏂瑰纺锘烘湰璺焏eadline绫讳技銆
cfq_queue浼氩硅繘鍏ラ槦鍒楃殑姣忎竴涓璇锋眰杩涜屼袱娆″叆阒燂纴涓涓鏀捐繘fifo涓锛屽彟涓涓鏀捐繘鎸夎块梾镓囧尯椤哄簭浣滀负key镄勭孩榛戞爲涓銆
榛樿や粠绾㈤粦镙戜腑鍙栬锋眰杩涜屽勭悊锛屽綋璇锋眰镄勫欢镞舵椂闂磋揪鍒癫eadline镞讹纴灏变粠绾㈤粦镙戜腑鍙栫瓑寰呮椂闂存渶闀跨殑杩涜屽勭悊锛屼互淇濊瘉璇锋眰涓嶈楗挎汇
杩椤氨鏄鏁翠釜cfq镄勮皟搴︽祦绋嬶纴褰撶劧鍏朵腑杩樻湁寰埚氱粏鏋濇汤鑺傛病链変氦浠o纴姣斿傚悎骞跺勭悊浠ュ强椤哄簭澶勭悊绛夌瓑銆
1.2 cfq镄勫弬鏁拌皟鏁
鐞呜В鏁翠釜璋冨害娴佺▼链夊姪浜庢垜浠鍐崇瓥濡备綍璋冩暣cfq镄勭浉鍏冲弬鏁般傛墍链塩fq镄勫彲璋冨弬鏁伴兘鍙浠ュ湪/sys/class/block/sda/queue/iosched/鐩褰曚笅镓惧埌锛屽綋铹讹纴鍦ㄤ綘镄勭郴缁熶笂锛岃峰皢sda镟挎崲涓虹浉搴旂殑纾佺洏钖岖О銆傛垜浠𨱒ョ湅涓涓嬮兘链変粈涔堬细
杩欎簺鍙傛暟閮ㄥ垎鏄璺熸満姊扮‖鐩樼佸ご瀵婚亾鏂瑰纺链夊叧镄勶纴濡傛灉鍏惰存槑浣犵湅涓嶆哕锛岃峰厛琛ュ厖鐩稿叧鐭ヨ瘑锛
back_seek_max:纾佸ご鍙浠ュ悜钖庡诲潃镄勬渶澶ц寖锲达纴榛樿ゅ间负16M銆
back_seek_penalty:钖戝悗瀵诲潃镄勬儵缃氱郴鏁般傝繖涓鍊兼槸璺熷悜鍓嶅诲潃杩涜屾瘆杈幂殑銆
浠ヤ笂涓や釜鏄涓轰简阒叉㈢佸ご瀵婚亾鍙戠敓鎶栧姩钥屽艰嚧瀵诲潃杩囨参钥岃剧疆镄勚傚熀链镐濊矾鏄杩欐牱锛屼竴涓猧o璇锋眰鍒版潵镄勬椂鍊欙纴cfq浼氭牴鎹鍏跺诲潃浣岖疆棰勪及涓涓嫔叾纾佸ご瀵婚亾鎴愭湰銆
璁剧疆涓涓链澶у糱ack_seek_max锛屽逛簬璇锋眰镓璁块梾镄勬墖鍖哄彿鍦ㄧ佸ご钖庢柟镄勮锋眰锛屽彧瑕佸诲潃锣冨洿娌℃湁瓒呰繃杩欎釜鍊硷纴cfq浼氩儚钖戝墠瀵诲潃镄勮锋眰涓镙峰勭悊瀹冦
鍐嶈剧疆涓涓璇勪及鎴愭湰镄勭郴鏁痈ack_seek_penalty锛岀浉瀵逛簬纾佸ご钖戝墠瀵诲潃锛屽悜钖庡诲潃镄勮窛绂讳负1/2(1/back_seek_penalty)镞讹纴cfq璁や负杩欎袱涓璇锋眰瀵诲潃镄勪唬浠锋槸鐩稿悓銆
杩欎袱涓鍙傛暟瀹为檯涓婃槸cfq鍒ゆ柇璇锋眰钖埚苟澶勭悊镄勬浔浠堕檺鍒讹纴鍑′簨澶嶅悎杩欎釜𨱒′欢镄勮锋眰锛岄兘浼氩敖閲忓湪链娆¤锋眰澶勭悊镄勬椂鍊欎竴璧峰悎骞跺勭悊銆
fifo_expire_async:璁剧疆寮傛ヨ锋眰镄勮秴镞舵椂闂淬
钖屾ヨ锋眰鍜屽纾姝ヨ锋眰鏄鍖哄垎涓嶅悓阒熷垪澶勭悊镄勶纴cfq鍦ㄨ皟搴︾殑镞跺欎竴鑸𨱍呭喌閮戒细浼桦厛澶勭悊钖屾ヨ锋眰锛屼箣钖庡啀澶勭悊寮傛ヨ锋眰锛岄櫎闱炲纾姝ヨ锋眰绗﹀悎涓婅堪钖埚苟澶勭悊镄勬浔浠堕檺鍒惰寖锲村唴銆
褰撴湰杩涚▼镄勯槦鍒楄璋冨害镞讹纴cfq浼氢紭鍏堟镆ユ槸钖︽湁寮傛ヨ锋眰瓒呮椂锛屽氨鏄瓒呰繃fifo_expire_async鍙傛暟镄勯檺鍒躲傚傛灉链夛纴鍒欎紭鍏埚彂阃佷竴涓瓒呮椂镄勮锋眰锛屽叾浣栾锋眰浠岖劧鎸夌収浼桦厛绾т互鍙婃墖鍖虹紪鍙峰ぇ灏忔潵澶勭悊銆
fifo_expire_sync:杩欎釜鍙傛暟璺熶笂闱㈢殑绫讳技锛屽尯鍒鏄鐢ㄦ潵璁剧疆钖屾ヨ锋眰镄勮秴镞舵椂闂淬
slice_idle:鍙傛暟璁剧疆浜嗕竴涓绛夊緟镞堕棿銆傝繖璁ヽfq鍦ㄥ垏鎹cfq_queue鎴杝ervice tree镄勬椂鍊欑瓑寰呬竴娈垫椂闂达纴鐩镄勬槸鎻愰珮链烘扮‖鐩樼殑钖炲悙閲忋
涓鑸𨱍呭喌涓嬶纴𨱒ヨ嚜钖屼竴涓猚fq_queue鎴栬却ervice tree镄処O璇锋眰镄勫诲潃灞閮ㄦф洿濂斤纴镓浠ヨ繖镙峰彲浠ュ噺灏戠佺洏镄勫诲潃娆℃暟銆傝繖涓鍊煎湪链烘扮‖鐩树笂榛樿や负闱为浂銆
褰撶劧鍦ㄥ浐镐佺‖鐩樻垨钥呯‖RAID璁惧囦笂璁剧疆杩欎釜鍊间负闱为浂浼氶檷浣庡瓨鍌ㄧ殑鏁堢巼锛屽洜涓哄浐镐佺‖鐩樻病链夌佸ご瀵诲潃杩欎釜姒傚康锛屾墍浠ュ湪杩欐牱镄勮惧囦笂搴旇ヨ剧疆涓0锛屽叧闂姝ゅ姛鑳姐
group_idle:杩欎釜鍙傛暟涔熻窡涓娄竴涓鍙傛暟绫讳技锛屽尯鍒鏄褰揷fq瑕佸垏鎹cfq_group镄勬椂鍊欎细绛夊緟涓娈垫椂闂淬
鍦╟group镄勫満鏅涓嬶纴濡傛灉鎴戜滑娌跨敤slice_idle镄勬柟寮忥纴闾d箞绌鸿浆绛夊緟鍙鑳戒细鍦╟group缁勫唴姣忎釜杩涚▼镄刢fq_queue鍒囨崲镞跺彂鐢熴
杩欐牱浼氩傛灉杩欎釜杩涚▼涓鐩存湁璇锋眰瑕佸勭悊镄勮瘽锛岄偅涔堢洿鍒拌繖涓猚group镄勯厤棰濊钥楀敖锛屽悓缁勪腑镄勫叾瀹冭繘绋嬩篃鍙鑳芥棤娉曡璋冨害鍒般傝繖镙蜂细瀵艰嚧钖岀粍涓镄勫叾瀹冭繘绋嬮タ姝昏屼骇鐢烮O镐ц兘鐡堕堛
鍦ㄨ繖绉嶆儏鍐典笅锛屾垜浠鍙浠ュ皢slice_idle 锛 0钥実roup_idle 锛 8銆傝繖镙风┖杞绛夊緟灏辨槸浠cgroup涓哄崟浣嶈繘琛岀殑锛岃屼笉鏄浠cfq_queue镄勮繘绋嬩负鍗曚綅杩涜岋纴浠ラ槻姝涓婅堪闂棰树骇鐢熴
low_latency:杩欎釜鏄鐢ㄦ潵寮钖鎴栧叧闂珰fq镄勪绠寤舵椂锛坙ow latency锛夋ā寮忕殑寮鍏炽
褰撹繖涓寮鍏虫墦寮镞讹纴cfq灏嗕细镙规嵁target_latency镄勫弬鏁拌剧疆𨱒ュ规疮涓涓杩涚▼镄勫垎鐗囨椂闂达纸slice time锛夎繘琛岄吨鏂拌$畻銆
杩椤皢链夊埄浜庡瑰闷钖愰噺镄勫叕骞筹纸榛樿ゆ槸瀵规椂闂寸墖鍒嗛厤镄勫叕骞筹级銆
鍏抽棴杩欎釜鍙傛暟锛堣剧疆涓0锛夊皢蹇界暐target_latency镄勫笺傝繖灏嗕娇绯荤粺涓镄勮繘绋嫔畬鍏ㄦ寜镦ф椂闂寸墖鏂瑰纺杩涜孖O璧勬簮鍒嗛厤銆傝繖涓寮鍏抽粯璁ゆ槸镓揿紑镄勚
鎴戜滑宸茬粡鐭ラ亾cfq璁捐′笂链夆灭┖杞钬濓纸idling锛夎繖涓姒傚康锛岀洰镄勬槸涓轰简鍙浠ヨ╄繛缁镄勮诲啓镎崭綔灏藉彲鑳藉氱殑钖埚苟澶勭悊锛屽噺灏戠佸ご镄勫诲潃镎崭綔浠ヤ究澧炲ぇ钖炲悙閲忋
濡傛灉链夎繘绋嬫绘槸寰埚揩镄勮繘琛岄‘搴忚诲啓锛岄偅涔埚畠灏嗗洜涓篶fq镄勭┖杞绛夊緟锻戒腑鐜囧緢楂樿屽艰嚧鍏跺畠闇瑕佸勭悊IO镄勮繘绋嫔搷搴旈熷害涓嬮檷锛屽傛灉鍙︿竴涓闇瑕佽皟搴︾殑杩涚▼涓崭细鍙戝嚭澶ч噺椤哄簭IO琛屼负镄勮瘽锛岀郴缁熶腑涓嶅悓杩涚▼IO钖炲悙閲忕殑琛ㄧ幇灏变细寰堜笉鍧囱銆
灏辨瘆濡傦纴绯荤粺鍐呭瓨镄刢ache涓链夊緢澶氲剰椤佃佸啓锲炴椂锛屾岄溃鍙堣佹墦寮涓涓娴忚埚櫒杩涜屾搷浣滐纴杩欐椂鑴忛〉鍐椤洖镄勫悗鍙拌屼负灏卞緢鍙鑳戒细澶ч噺锻戒腑绌鸿浆镞堕棿锛岃屽艰嚧娴忚埚櫒镄勫皬閲廔O涓鐩寸瓑寰咃纴璁╃敤鎴锋劅瑙夋祻瑙埚櫒杩愯屽搷搴旈熷害鍙樻参銆
杩欎釜low_latency涓昏佹槸瀵硅繖绉嶆儏鍐佃繘琛屼紭鍖栫殑阃夐”锛屽綋鍏舵墦寮镞讹纴绯荤粺浼氭牴鎹畉arget_latency镄勯厤缃瀵瑰洜涓哄懡涓绌鸿浆钥屽ぇ閲忓崰鐢↖O钖炲悙閲忕殑杩涚▼杩涜岄檺鍒讹纴浠ヨ揪鍒颁笉钖岃繘绋娅O鍗犵敤镄勫闷钖愰噺镄勭浉瀵瑰潎琛°傝繖涓寮鍏虫瘆杈冨悎阃傚湪绫讳技妗岄溃搴旂敤镄勫満鏅涓嬫墦寮銆
target_latency:褰搇ow_latency镄勫间负寮钖鐘舵佹椂锛宑fq灏嗘牴鎹杩欎釜鍊奸吨鏂拌$畻姣忎釜杩涚▼鍒嗛厤镄処O镞堕棿鐗囬暱搴︺
quantum:杩欎釜鍙傛暟鐢ㄦ潵璁剧疆姣忔′粠cfq_queue涓澶勭悊澶氩皯涓狪O璇锋眰銆傚湪涓涓阒熷垪澶勭悊浜嬩欢锻ㄦ湡涓锛岃秴杩囱繖涓鏁板瓧镄処O璇锋眰灏嗕笉浼氲澶勭悊銆傝繖涓鍙傛暟鍙瀵瑰悓姝ョ殑璇锋眰链夋晥銆
slice_sync:褰扑竴涓猚fq_queue阒熷垪琚璋冨害澶勭悊镞讹纴瀹冨彲浠ヨ鍒嗛厤镄勫勭悊镐绘椂闂存槸阃氲繃杩欎釜鍊兼潵浣滀负涓涓璁$畻鍙傛暟鎸囧畾镄勚傚叕寮忎负锛歵ime_slice = slice_sync + (slice_sync/5 * (4 - prio))銆傝繖涓鍙傛暟瀵瑰悓姝ヨ锋眰链夋晥銆
slice_async:杩欎釜鍊艰窡涓娄竴涓绫讳技锛屽尯鍒鏄瀵瑰纾姝ヨ锋眰链夋晥銆
slice_async_rq:杩欎釜鍙傛暟鐢ㄦ潵闄愬埗鍦ㄤ竴涓狲lice镄勬椂闂磋寖锲村唴锛屼竴涓阒熷垪链澶氩彲浠ュ勭悊镄勫纾姝ヨ锋眰涓鏁般傝锋眰琚澶勭悊镄勬渶澶т釜鏁拌缮璺熺浉鍏宠繘绋嬭璁剧疆镄刬o浼桦厛绾ф湁鍏炽
1.3 cfq镄処OPS妯″纺
鎴戜滑宸茬粡鐭ラ亾锛岄粯璁ゆ儏鍐典笅cfq鏄浠ユ椂闂寸墖鏂瑰纺鏀鎸佺殑甯︿紭鍏堢骇镄勮皟搴︽潵淇濊瘉IO璧勬簮鍗犵敤镄勫叕骞炽
楂树紭鍏堢骇镄勮繘绋嫔皢寰楀埌镟村氱殑镞堕棿鐗囬暱搴︼纴钥屼绠浼桦厛绾х殑杩涚▼镞堕棿鐗囩浉瀵硅缉灏忋
褰撴垜浠镄勫瓨鍌ㄦ槸涓涓楂橀熷苟涓旀敮鎸丯CQ锛埚师鐢熸寚浠ら槦鍒楋级镄勮惧囩殑镞跺欙纴鎴戜滑链濂藉彲浠ヨ╁叾鍙浠ヤ粠澶氢釜cfq阒熷垪涓澶勭悊澶氲矾镄勮锋眰锛屼互渚挎彁鍗嘚CQ镄勫埄鐢ㄧ巼銆
姝ゆ椂浣跨敤镞堕棿鐗囩殑鍒嗛厤鏂瑰纺鍒嗛厤璧勬簮灏辨樉寰椾笉钖堟椂瀹滀简锛屽洜涓哄熀浜庢椂闂寸墖镄勫垎閰嶏纴钖屼竴镞跺埢链澶氲兘澶勭悊镄勮锋眰阒熷垪鍙链変竴涓銆
杩欐椂锛屾垜浠闇瑕佸垏鎹cfq镄勬ā寮忎负IOPS妯″纺銆傚垏鎹㈡柟寮忓緢绠鍗曪纴灏辨槸灏唖lice_idle=0鍗冲彲銆傚唴镙镐细镊锷ㄦ娴嬩綘镄勫瓨鍌ㄨ惧囨槸钖︽敮鎸丯CQ锛屽傛灉鏀鎸佺殑璇漜fq浼氲嚜锷ㄥ垏鎹涓篒OPS妯″纺銆
鍙﹀栵纴鍦ㄩ粯璁ょ殑锘轰簬浼桦厛绾х殑镞堕棿鐗囨柟寮忎笅锛屾垜浠鍙浠ヤ娇鐢╥onice锻戒护𨱒ヨ皟鏁磋繘绋嬬殑IO浼桦厛绾с傝繘绋嬮粯璁ゅ垎閰岖殑IO浼桦厛绾ф槸镙规嵁杩涚▼镄刵ice鍊艰$畻钥屾潵镄勶纴璁$畻鏂规硶鍙浠ュ湪man ionice涓鐪嫔埌锛岃繖閲屼笉鍐嶅帘璇濄
2銆乨eadline锛氭渶缁堟湡闄愯皟搴
deadline璋冨害绠楁硶鐩稿筩fq瑕佺亩鍗曞緢澶氥傚叾璁捐$洰镙囨槸锛
鍦ㄤ缭璇佽锋眰鎸夌収璁惧囨墖鍖虹殑椤哄簭杩涜岃块梾镄勫悓镞讹纴鍏奸【鍏跺畠璇锋眰涓嶈楗挎伙纴瑕佸湪涓涓链缁堟湡闄愬墠琚璋冨害鍒般
鎴戜滑鐭ラ亾纾佸ご瀵圭佺洏镄勫婚亾鏄鍙浠ヨ繘琛岄‘搴忚块梾鍜岄殢链鸿块梾镄勶纴锲犱负瀵婚亾寤舵椂镞堕棿镄勫叧绯伙纴椤哄簭璁块梾镞禝O镄勫闷钖愰噺镟村ぇ锛岄殢链鸿块梾镄勫闷钖愰噺灏忋
濡傛灉鎴戜滑𨱍充负涓涓链烘扮‖鐩樿繘琛屽闷钖愰噺浼桦寲镄勮瘽锛岄偅涔埚氨鍙浠ヨ╄皟搴﹀櫒鎸夌収灏介噺澶嶅悎椤哄簭璁块梾镄処O璇锋眰杩涜屾帓搴忥纴涔嫔悗璇锋眰浠ヨ繖镙风殑椤哄簭鍙戦佺粰纭鐩桡纴灏卞彲浠ヤ娇IO镄勫闷钖愰噺镟村ぇ銆
浣嗘槸杩欐牱锅氢篃链夊彟涓涓闂棰桡纴灏辨槸濡傛灉姝ゆ椂鍑虹幇浜嗕竴涓璇锋眰锛屽畠瑕佽块梾镄勭侀亾绂荤洰鍓岖佸ご镓鍦ㄧ侀亾寰堣繙锛屽簲鐢ㄧ殑璇锋眰鍙埚ぇ閲忛泦涓鍦ㄧ洰鍓岖侀亾闄勮繎銆
瀵艰嚧澶ч噺璇锋眰涓鐩翠细琚钖埚苟鍜屾彃阒熷勭悊锛岃岄偅涓瑕佽块梾姣旇缉杩灭侀亾镄勮锋眰灏嗗洜涓轰竴鐩翠笉鑳借璋冨害钥岄タ姝汇
deadline灏辨槸杩欐牱涓绉嶈皟搴﹀櫒锛岃兘鍦ㄤ缭璇両O链澶у闷钖愰噺镄勬儏鍐典笅锛屽敖閲忎娇杩灭璇锋眰鍦ㄤ竴涓链熼檺鍐呰璋冨害钥屼笉琚楗挎荤殑璋冨害鍣ㄣ