[操作系統]設備分配中的數據結構:設備控制表(DCT)、控制器控制表(COCT)、通道控制表(CHCT)和系統設備表(SDT)


在多道程序環境下,系統中的設備供所有進程共享。為防止諸進程對系統資源的無序競爭,特規定系統設備不允許用戶自行使用,必須由系統統一分配。每當進程向系統提出I/O請求時,只要是可能和安全的,設備分配程序便按照一定的策略,把設備分配給請求用戶(進程)。

在有的系統中,為了確保在CPU與設備之間能進行通信,還應分配相應的控制器和通道。

設備分配中的數據結構

---- 在進行設備分配時,通常都需要借助於一些表格的幫助。在表格中記錄了相應設備或控制器的狀態及對設備或控制器進行控制所需的信息。

在進行設備分配時所需的數據結構(表格)由:設備控制表(DCT)、控制器控制表(COCT)、通道控制表(CHCT)和系統設備表(SDT)等。

設備控制表(DCT)

系統為每一個設備都配置了一張設備控制表,用於記錄本設備的情況:

----- 設備類型:type、設備標識符:deviceid、設備狀態:等待/不等待 忙/閑、指向控制器表的指針、重復執行次數或時間、設備隊列的隊首指針。

設備控制表中,除了有用於指示設備類型的字段type和設備標識字段deviceid外,還應含有下列字段:

----- 設備隊列隊首指針。凡因請求本設備而未得到滿足的進程,其PCB都應按照一定的策略排成一個隊列,稱該隊列為設備請求隊列或設備隊列。

----- 設備狀態。當設備自身正處於使用狀態時,應將設備的忙/閑標志置“1”。若與該設備相連接的控制器或通道正忙,也不能啟動該設備,此時應將設備的等待標志置“1”。

----- 與設備連接的控制器表指針。該指針指向與該設備所連接的控制器的控制表,在設備到主機之間具有多條通路的情況下,一個設備將與多個控制器相連接。此時,在DCT中還應設置多個控制器表指針。

----- 重復執行次數。由於外部設備在傳送數據時,較易發生數據傳送錯誤,因而在許多系統中,如果發生傳送錯誤,並不立即認為傳送失敗,而是

令它重新傳送,並由系統規定設備在工作中發生錯誤時應重復執行的次數。

控制器控制表、通道控制表和系統設備表

1)控制器控制表(COCT,Controller control table)。系統為每一個控制器都設置了一張用於記錄本控制器情況的控制器控制表。其中記錄了:

>控制器標識符-controllerid、控制器狀態-忙/閑、與控制器連接的通道表指針、控制器隊列的隊首指針、控制器隊列的隊尾指針。

2)通道控制表(CHCT,Channel control table)。每個通道都配有一張通道控制表。其中記錄了:

> 通道標識符-channelid、通道狀態-忙/閑、與通道連接的控制器表的指針通道隊列的隊首指針、通道隊列的隊尾指針。

3)系統設備表(SDT,System device table)。這是系統范圍的數據結構,其中記錄了系統中全部設備的情況。每個設備占一個表目,其中包括有

>設備類型、設備標識符、設備控制表及設備驅動程序的入口等項。

設備分配時應考慮的因素

設備的固有屬性

---- 在分配設備時,首先應考慮與設備分配有關的設備屬性。設備的固有屬性可分成三種:獨占性,指這種設備在一段時間內只允許一個進程獨占,即“臨界資源”;共享性,指這種設備允許多個進程同時共享;可虛擬性,設備本身雖是獨占設備,但經過某種技術處理,可以把它改造成虛擬設備。

根據設備的固有屬性應采取不同的分配策略:
1)獨占設備。對於獨占設備,應采用獨享分配策略,即將一個設備分配給某進程后,便由該進程獨占,直至該進程完成或釋放該設備,然后系統才能再將該設備分配給其他進程使用。缺點:設備得不到充分利用,而且還可能引起死鎖。
2)共享設備。對於共享設備,可同時分配給多個進程使用,此時需注意對這些進程訪問該設備的先后次序進行合理的調度。
3)可虛擬設備。由於可虛擬設備是指一台物理設備在采用虛擬技術后,可變成多台邏輯上的虛擬設備,因而說,一台可虛擬設備是可共享的設備,
可以將它同時分配給多個進程使用,並對訪問該(物理)設備的先后次序進行控制。

設備分配算法

---- 對設備進行分配的算法,與進程調度的算法有些相似之處,但前者相對簡單,通常只采用以下兩種分配算法:
1)先來先服務。當有多個進程對同一設備提出I/O請求時,該算法是根據諸進程對某設備提出請求的先后次序,將這些進程排成一個設備請求隊列,設備分配程序總是把設備首先分配給隊首進程。
2)優先級高者優先。在進程調度中的這種策略,是優先權高的進程優先獲得處理機。如果對這種高優先權進程所提出的I/O請求也賦予高優先權,顯然有助於這種進程盡快完成。

在利用該算法形成設備隊列時,將優先權高的進程排在設備隊列前面,而對於優先級相同的I/O請求,則按先來先服務原則排隊。

設備分配時的安全性

---- 從進程運行的安全性考慮,設備分配有以下兩種方式。
1)安全分配方式。在這種分配方式中,每當進程發出I/O請求時,便進入阻塞狀態,直到其I/O操作完成時才被喚醒。
在采用這種分配策略時,一旦進程已經請求(獲得)某種設備(資源)后便阻塞,使該進程不可能再請求其他任何資源,因此,這種分配方式已經摒棄了造成死鎖的四個必要條件之一的"請求和保持"條件,從而使設備分配是安全的。缺點:進程進展緩慢,即CPU與I/O設備是串行工作的。

2)不安全分配方式。在這種分配方式中,進程在發出I/O請求后仍繼續運行,需要時又發出第二個I/O請求、第三個I/O請求等。僅當進程所請求的設備已被另一進程占用時,請求進程才進入阻塞狀態。這種分配方式的優點是:一個進程可同時操作多個設備,使進程推進迅速。

缺點:分配不安全,因為它可能具備“請求和保持”條件,從而可能造成死鎖。因此,在設備分配程序中,還應再增加一個功能,以用於對本次的設備分配是否會發生死鎖進行安全性計算,僅當計算結果說明分配是安全的情況下才進行設備分配。

獨占設備的分配程序

基本的設備分配程序

---- 當某進程提出I/O請求后,系統的設備分配程序可按下述步驟進行設備分配:

1)分配設備

-- 首先根據I/O請求中的物理設備名,查找系統設備表(SDT),從中找出該設備的DCT(設備分配表),再根據DCT中的設備狀態字段,可知

該設備是否正忙。若忙,便將請求I/O進程的PCB掛在設備隊列上;否則,便按照一定的算法來計算本次設備分配的安全性。如果不會導致系統

進入不安全狀態,便將設備分配給請求進程;否則,仍將其PCB插入設備等待隊列。

2)分配控制器

-- 在系統把設備分配給請求I/O的進程后,再到其DCT(指向控制器表的指針)中找出與該設備連接的控制器的COCT(控制器控制表),從COCT

的狀態字段中可知該控制器是否忙碌。若忙,便將請求I/O進程的PCB掛在該控制器的等待隊列上;否則,便將該控制器分配給進程。

3)分配通道

-- 通過COCT中與控制器連接的通道表指針,找到與該控制器連接的通道的CHCT(通道控制表),再根據CHCT內的狀態信息,可知該通道是否

忙碌。若忙,便將請求I/O的進程掛在該通道的等待隊列上;否則,將該通道分配給進程。

-- 只有在設備、控制器和通道三者都分配成功時,這次的設備分配才算成功。然后,便可啟動該I/O設備進行數據傳送。

設備分配程序的改進

---- 仔細研究上述基本的設備分配程序后可以發現:

進程是以物理設備名來提出I/O請求的;采用的是單通路的I/O系統結構,容易產生“瓶頸”現象。

為此,應從以下兩方面對基本的設備分配程序加以改進,以使獨占設備的分配程序具有更強的靈活性,並提高分配的成功率。

1)增加設備的獨立性

-- 為了獲得設備的獨立性,進程應使用邏輯設備名請求I/O。這樣,系統首先從SDT中找出第一個該類設備的DCT。

若該設備忙,又查找第二個該類設備的DCT,僅當所有該類設備都忙時,才把進程掛在該類設備的等待隊列上;

而只要有一個該類設備可用,系統便進一步計算分配該類設備的安全性。

2)考慮多通路情況

-- 為了防止在I/O系統中出現“瓶頸”現象(通道不足),通常都采用多通路的I/O系統結構。

此時對控制器和通道的分配同樣要經過幾次反復,即若設備(控制器)所連接的第一個控制器(通道)忙時,應查看其所連接的第二個控制器(通道),

僅當所有的控制器(通道)都忙時,此次的控制器(通道)分配才算失敗,才把進程掛在控制器(通道)的等待隊列上。

而只要有一個控制器(通道)可用,系統便可將它分配給進程。



代碼實現:

  • 結構體聲明
struct sdt//系統設備表
{
	char name;//設備名稱
	char type;//設備類型
	struct sdt *next;
};

struct block//阻塞設備
{
	char pname;//申請設備進程名
	char ename;//設備名
	struct block *next;
};

struct chct//通道
{
	char name;//通道名稱
	int  state;//通道狀態
	struct block *next;//通道被占用造成的阻塞隊列
};

struct coct//控制器表
{
	char name;//控制器名稱
	int state;//控制器狀態
	struct chct *chct;//設備通道
	struct block *next;//控制器被占用造成的阻塞隊列
};

struct dct//設備控制表
{
	int state; //設備狀態
	struct sdt *sdt;//系統設備
	struct coct *coct;//設備控制器
	struct block *next;//設備被占用造成的阻塞隊列
};
  • 定義
sdt *s[20];//設備

dct *d[20];//設備控制

coct *co[20];//控制器

chct *ch1,*ch2;//通道1,通道2

block *b;

int e=4;//設備數,初始為4

int c=3;//控制器數,初始為3
  • 初始化
void init()//初始化
{
	for(int i=0;i<4;i++)
	{
		s[i]=new(sdt);
		d[i]=new(dct);
		d[i]->state=0;
		d[i]->sdt=s[i];
		d[i]->next=new(block);
    d[i]->next->next=NULL;
	}
  s[0]->name='k';
	s[1]->name='m';
	s[2]->name='t';
	s[3]->name='p';
	s[0]->type='i';
	s[1]->type='i';
	s[2]->type='o';
	s[3]->type='o';

	for(int i=1;i<4;i++)
	{
		co[i]=new(coct);
		co[i]->state=0;
		co[i]->next=new(block);
		co[i]->next->next=NULL;
	}
  co[1]->name='1';
	co[2]->name='2';
	co[3]->name='3';

	ch1=new (chct);
	ch2=new (chct);
	ch1->name='1';
	ch1->state=0;
	ch1->next=new(block);
	ch1->next->next=NULL;
	ch2->name='2';
	ch2->state=0;
	ch2->next=new(block);
	ch2->next->next=NULL;

	co[1]->chct=ch1;
	co[2]->chct=ch2;
	co[3]->chct=ch2;

	d[0]->coct=co[1];
	d[1]->coct=co[1];
	d[2]->coct=co[2];
	d[3]->coct=co[3];
}

增加設備

void add()
{
	int i;
	char a;
	char b;
	cout<<"設備名稱:"<<endl;
	cin>>a;
	cout<<"設備類型:"<<endl;
	cin>>b;
	for(i=0;i<e;i++)
		if(d[i]->sdt->name==a)
			cout<<"設備已存在!"<<endl;
	if(i==e)
	{
	s[e]=new(sdt);
	d[e]=new(dct);
	s[e]->name=a;
	s[e]->type=b;
	d[e]->sdt=s[e];
	d[e]->state=0;
	d[e]->next=new(block);
	d[e]->next->next=NULL;
	e++;
	cout<<"是否新建控制器?(y/n)"<<endl;
	cin>>a;
	if(a=='y')
	{
		char g;
		int flag=0;
		cout<<"請輸入新增控制器名稱:"<<endl;
		cin>>g;
		if(flag==0)
		{
			for(int k=1;k<=c;k++)
				if(co[k]->name==g)
				{
					flag=1;
					cout<<"該控制器已存在,請重新輸入!"<<endl;
			        cin>>g;
				}
		}
		co[c+1]=new(coct);
		co[c+1]->name=g;
		co[c+1]->state=0;
		co[c+1]->next=new(block);
		co[c+1]->next->next=NULL;
		d[e-1]->coct=co[c+1];
		c++;
		cout<<"請選擇通道(1/2)"<<endl;
		char f;
		cin>>f;
		if(f=='1')
			co[c]->chct=ch1;
		if(f=='2')
			co[c]->chct=ch2;

		cout<<"設備添加成功!"<<endl;
	}
	else if(a=='n')
    {
		cout<<"當前已存在的控制器有:"<<endl;
		for(int i=1;i<=c;i++)
			cout<<co[i]->name<<endl;
		cout<<"輸入選擇的控制器名稱:"<<endl;
		char cz;
		cin>>cz;
		for(int j=1;j<=c;j++)
		{
			if(cz==co[j]->name)
			{
				cout<<"設備添加成功!"<<endl;
				d[e-1]->coct=co[j];
			}
		}
	}
	}
}

刪除設備

void del()
{
	int b;
	block *p;
	cout<<"設備名稱:"<<endl;
	char c;
	cin>>c;
	for(int i=0;i<e;i++)
	{
		if(d[i]->sdt->name==c)
		{
			if(d[i]->state==1)
				cout<<"用戶進程正在使用設備,無法刪除!"<<endl;
			else
			if(d[i]->next->next!=NULL)//設備阻塞隊列不空
			{
				p=d[i]->next->next;
				for(;p->ename!=c&&p->next!=NULL;)
					p=p->next;
					cout<<"用戶進程"<<p->pname<<"等待使用設備,無法刪除!"<<endl;
			}
			else
			if(d[i]->coct->next->next!=NULL)//控制器阻塞隊列不空
			{
				p=d[i]->coct->next->next;
				for(;p->ename!=c&&p->next!=NULL;)
					p=p->next;
					cout<<"用戶進程"<<p->pname<<"等待使用設備,無法刪除!"<<endl;
			}
			else
			if(d[i]->coct->chct->next->next!=NULL)//通道阻塞隊列不空
			{
				p=d[i]->coct->chct->next->next;
				for(;p->ename!=c&&p->next!=NULL;)
					p=p->next;
					cout<<"用戶進程"<<p->pname<<"等待使用設備,無法刪除!"<<endl;
			}
			else
			{
				cout<<"設備刪除成功!"<<endl;
				char coc=d[i]->coct->name;
				for(int j=i;j<e;j++)
					d[j]=d[j+1];
				e--;
				cout<<"刪除控制器(y/n)?"<<endl;
				char a;
				cin>>a;
				if(a=='y')
				{
					for(b=0;b<e;b++)
						if(d[b]->coct->name==coc)
							cout<<"控制器"<<coc<<"正在使用,無法刪除!"<<endl;
					if(b==e-1)
					{
						int j=0;
						while(co[j]->name!=coc)
							j++;
						for(j;j<=c;j++)
							co[j]=co[j+1];
				        c--;
						cout<<"控制器刪除成功!"<<endl;
					}
					break;
				}
				else if(a=='n')
					break;
			}
		}
	}
}

請求設備

void require()
{
	block *p;
	char ename,pname;
	cout<<"設備名稱:"<<endl;
	cin>>ename;
	cout<<"進程名稱:"<<endl;
	cin>>pname;
	for(int i=0;i<e;i++)
	{
		if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==0 &&d[i]->coct->chct->state==0)
		{
			d[i]->state=1;
			d[i]->coct->state=1;
			d[i]->coct->chct->state=1;
			cout<<"申請成功!"<<endl;
		}
		else
		if(d[i]->sdt->name==ename&&d[i]->state==1)
		{
			cout<<"設備"<<d[i]->sdt->name<<"被占用,進程阻塞!"<<endl;
			b=new(block);
			b->pname=pname;
			b->ename=ename;
			p=d[i]->next;
			while(p->next!=NULL)
				p=p->next;
			p->next=b;
			b->next=NULL;
		}
		else
		if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==1)
		{
			cout<<"控制器"<<d[i]->coct->name<<"被占用,進程阻塞!"<<endl;
			b=new(block);
			b->pname=pname;
			b->ename=ename;
			p=d[i]->coct->next;
			while(p->next!=NULL)
				p=p->next;
			p->next=b;
			b->next=NULL;
		}
		else
		if(d[i]->sdt->name==ename &&d[i]->state==0 &&d[i]->coct->state==0 &&d[i]->coct->chct->state==1)
		{
			cout<<"通道"<<d[i]->coct->chct->name<<"被占用,進程阻塞!"<<endl;
			b=new(block);
			b->pname=pname;
			b->ename=ename;
			p=d[i]->coct->chct->next;
			while(p->next!=NULL)
				p=p->next;
			p->next=b;
			b->next=NULL;
		}
	}
}

回收設備

void callback()
{
	int i,j;
  char n;
	int b;
	cout<<"設備名稱:"<<endl;
	cin>>n;
	for(int i=0;i<e;i++)
	{
		if(d[i]->sdt->name==n)
		{
			if(d[i]->state==1)
			{
			    cout<<"設備"<<d[i]->sdt->name<<"回收成功!"<<endl;
			 	d[i]->coct->state=0;
			    d[i]->coct->chct->state=0;
			    d[i]->state=0;
			    if(d[i]->coct->chct->next->next!=NULL)
				{
				    cout<<"進程"<<d[i]->coct->chct->next->next->pname<<"已成功使用"<<d[i]->coct->chct->next->next->ename<<"設備!"<<endl;
				    for(b=0;b<e;b++)
					{
					if(d[i]->coct->chct->next->next->ename==d[b]->sdt->name)
					{
						d[b]->state=1;
						break;
					}
				}
				d[b]->coct->state=1;
				d[i]->coct->chct->state=1;
				block *p;
				p=d[i]->coct->chct->next;
				while(p->next->pname != d[i]->coct->chct->next->next->pname)
					p=p->next;
				p->next = p->next->next;
				break;
			}
			if(d[i]->coct->next->next!=NULL)
			{

				cout<<"進程"<<d[i]->coct->next->next->pname<<"已成功使用"<<d[i]->coct->next->next->ename<<"設備!"<<endl;
				for(b=0;b<e;b++)
				{
					if(d[i]->coct->next->next->ename==d[b]->sdt->name)
						d[b]->state=1;
				}
				d[i]->coct->state=1;
				d[i]->coct->chct->state=1;
				block *q;
				q=d[i]->coct->next;
				while(q->next->pname != d[i]->coct->next->next->pname)
					q=q->next;
				q->next = q->next->next;
				break;
			}
			if(d[i]->next->next!=NULL)
			{
				cout<<"進程"<<d[i]->next->next->pname<<"已成功使用"<<d[i]->next->next->ename<<"設備!"<<endl;
				for(int b=0;b<e;b++)
				{
					if(d[i]->next->next->ename==d[b]->sdt->name)
						d[b]->state=1;
				}

				d[i]->coct->state=1;
				d[i]->coct->chct->state=1;
				block *r;
				r=d[i]->next;
				while(r->next->pname != d[i]->next->next->pname)
					r=r->next;
				r->next = r->next->next;
				break;
			}
			else
			{
				for(int j=0;j<e;j++)
				{
					if(d[j]->coct->chct->next->next!=NULL)
					{
						cout<<"進程"<<d[j]->coct->chct->next->next->pname<<"已成功使用"<<d[j]->coct->chct->next->next->ename<<"設備!"<<endl;
						d[j]->coct->state=1;
						d[j]->coct->chct->state=1;
						block *p;
						p=d[j]->coct->chct->next;
						while(p->next->pname != d[j]->coct->chct->next->pname)
							p=p->next;
						p->next = p->next->next;
						break;
					}
					if(d[j]->coct->next->next!=NULL)
					{
						cout<<"進程"<<d[j]->coct->next->next->pname<<"已成功使用"<<d[j]->coct->next->next->ename<<"設備!"<<endl;
						d[j]->state=1;
						d[j]->coct->state=1;
						d[j]->coct->chct->state=1;
						block *q;
						q=d[j]->coct->next;
						while(q->next->pname != d[j]->coct->next->next->pname)
							q=q->next;
						q->next = q->next->next;
						break;
					}
					if(d[j]->next->next!=NULL)
					{
						cout<<"進程"<<d[j]->next->next->pname<<"已成功使用"<<d[j]->next->next->ename<<"設備!"<<endl;
						d[j]->state=1;
						d[j]->coct->state=1;
						d[j]->coct->chct->state=1;
						block *r;
						r=d[j]->next;
						while(r->next->pname != d[j]->next->next->pname)
							r=r->next;
						r->next = r->next->next;
						break;
					}
				}
				if(j==e)
					cout<<"無阻塞進程"<<endl;
			break;
			}
			}
			else
			{
				cout<<"設備閑置,無須回收!"<<endl;
				break;
			}
		}
	}
	if(i==e)
		cout<<"不存在該設備!"<<endl;
}

磁盤調度算法

//設備管理:磁盤調度
void FCFS(int array[],int m){
    int sum=0,j,i;
    double avg;
    cout<<"\n調度序列:"<<" ";
    for( i=0;i<m;i++)    {
        cout<<array[i]<<" ";
    }
    for(i=0,j=1;j<m;i++,j++)    {
        sum+=abs(array[j]-array[i]);
    }
    avg=sum/(m);
    cout<<"\n移動的總道數: "<<sum<<endl;
    cout<<"平均尋道時間: "<<avg<<endl;
    cout<<endl;
}

最短尋道時間優先算法

// 最短尋道時間優先算法
void ShortPath(int array[],int m)
{     int tmp;
    int k=1;
    int now,l,r,temp;
    int i,j;
    float sum=0,avg=0;
    for(i=0;i<m;i++)
        for(j=i+1;j<m;j++)
        {
            if(array[i]>array[j]) //將磁道號從小到大排序
            {
                temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
    cout<<"\n請輸入當前的磁道號:"; //輸入當前磁道號
    cin>>now;
    tmp=now;
    cout<<"最短尋道時間優先算法(SSTF)\n調度序列:";//輸出磁盤調度序列
    if(array[m-1]<=now)  //若被訪問的最大的磁道號小於當前的磁道號
        for(int x=m;x>0;x--)
        {
            sum+=now-array[x-1];
            cout<<array[x-1]<<" ";
            now=array[x-1];
        }
    
    else if(now<=array[0])  //若被訪問的最小的磁道號大於當前的磁道號
        for(int x=0;x<m;x++)
        {
            sum+=array[x]-now;
            cout<<array[x]<<" ";
            now=array[x];
        }
    //當前的磁道號的值在若所有被訪問的磁道號之間
    else{
        while(array[k]<=now) //確定當前磁道在已排的序列中的位置
        {  k++;    }
        l=k-1;
        r=k;
        int count=m;
        while(count>0)
        {
            if(now==array[0])
                while(r<m)
                {
                    cout<<array[r]<<" ";
                    count--;
                    sum+=array[r]-now;
                    now=array[r];
                    r++;
                }
            else if(now==array[m-1])
                while(l>=0)
                {
                    cout<<array[l]<<" ";
                    count--;
                    sum+=now-array[l];
                    now=array[l];
                    l--;
                }
            else
            {
                if((now-array[l])<=(array[r]-now))
                {
                    cout<<array[l]<<" ";
                    count--;
                    sum+=now-array[l];
                    now=array[l];
                    l--;
                }
                else
                {
                    cout<<array[r]<<" ";
                    count--;
                    sum+=array[r]-now;
                    now=array[r];
                    r++;
                }
            }
        }
    }
    
    for(int i=0;i<m;i++)
    {
        if(tmp==array[i])
        {
            m=m-1;
            break;
        }
    }
    avg=sum/(m);
    cout<<endl<<"平均尋道長度:"<<avg<<endl<<endl;//輸出平均尋道長度
}

SCAN算法

//SCAN算法
void Elevator(int array[],int m)  //掃描算法
{     int temp;
    int k=1;
    int now,d,l,r;
    int i,j;
    float sum=0,avg=0;
    for(i=0;i<m;i++)
        for(j=i+1;j<m;j++)
        {
            if(array[i]>array[j]) //將磁道號從小到大排序
            {
                temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
    cout<<"\n請輸入當前的磁道號:";//輸入當前磁道號
    cin>>now;
    cout<<"請選擇當前磁頭的移動方向:"<<endl<<endl;
    cout<<" 1. 向磁道號增加方向"<<endl;
    cout<<" 0. 向磁道號減小方向"<<endl<<endl;
    cin>>d;          //給出磁頭移動方向
    cout<<"掃描算法(SCAN)\n調度序列:";
    if(array[m-1]<=now)   //在序列右方
    {
        for(i=m-1;i>=0;i--)
        { cout<<array[i]<<" ";
            sum+=now-array[i];
            now=array[i];
        }
    }
    else
    {
        if(array[0]>=now) //在序列左方
        {
            for(i=0;i<m;i++)
            {  cout<<array[i]<<" ";
                sum+=array[i]-now;
                now=array[i];
            }
        }
        else  //在序列中間
        {
            while(array[k]<now)  //確定當前磁道在已排的序列中的位置
            {  k++;    }
            l=k-1;
            r=k;
            switch(d)
            {
                case 0:       //先向磁道號減小方向訪問
                {
                    while(l>=0)
                    {
                        cout<<array[l]<<" ";
                        sum+=now-array[l];
                        now=array[l];
                        l=l-1;
                    }
                    now=array[0];
                    for(j=r;j<m;j++)
                    {  cout<<array[j]<<" ";
                        sum+=array[j]-now;
                        now=array[j];
                    } break;
                }
                case 1:   //先向磁道號增加方向訪問
                {
                    while(r<m)
                    {
                        cout<<array[r]<<" ";
                        sum+=array[r]-now;
                        now=array[r];
                        r=r+1;
                    }
                    now=array[m-1];
                    for(j=l;j>=0;j--)
                    {  cout<<array[j]<<" ";
                        sum+=now-array[j];
                        now=array[j];
                    }break;
                }
                default: cout<<"輸入有誤"<<endl;
            }
        }
    }
    avg=sum/(m);
    cout<<endl<<"平均尋道長度:"<<avg<<endl<<endl;//輸出平均尋道長度
}
  • 功能菜單打印
void version_cipantiaodu() {
    cout<<endl<<endl;
    cout<<"      ┏━━━━━━━━━━━━━━━━━────────────────────━━━━━━┓"<<endl;
    cout<<"      ┃       設 備 管 理:磁 盤 調 度         ┃"<<endl;
    cout<<"      ┠───────────────────────────────────────────┨"<<endl;
    cout<<"      ┃          1.先來先服務                 ┃"<<endl;
    cout<<"      ┃          2.最短尋道時間優先           ┃"<<endl;
    cout<<"      ┃          3.SCAN算法                   ┃"<<endl;
    cout<<"      ┃          0.退出該算法                 ┃"<<endl;
    cout<<"      ┃                               ┃"<<endl;
    cout<<"      ┃       設計時間:20181228             ┃"<<endl;
    cout<<"      ┗━━━━━━━━━━━━━━━━━━━────────────────────━━━━┛"<<endl;
    cout<<endl<<endl;
}
  • 磁盤調度算法,從外部文件讀取 cidao.txt
void cipantiaodu(){
    int chioce;
    int flag=1;
    FILE *fp;
    int cidao[maxsize];
    int i=0,count;
    version_cipantiaodu();
    fp=fopen("cidao.txt","r+");
    if(fp==NULL){
        cout<<"can not find file!"<<endl;
        getchar();
        exit(0);
    }
    while(!feof(fp)){
        fscanf(fp,"%d",&cidao[i]);
        i++;
    }
    count=i-1;
    cout<<"磁盤訪問序列:"<<" ";
    for(i=0;i<count;i++){
        printf("%5d",cidao[i]);
    }
    cout<<endl;
    cout<<endl;
  • 選擇磁盤調度算法
    while(flag){
        cout<<"請選擇:";
        cin>>chioce;
        switch(chioce){
            case 1:
                FCFS(cidao,count);
                break;
            case 2:
                ShortPath(cidao,count);
                break;
            case 3:
                Elevator(cidao,count);
                break;
            case 0:
                flag=0;
                system("clear");
                break;
            default:
                cout<<"選擇錯誤"<<endl<<endl;
        }
    }
    getchar();
}
  • 主菜單打印
void menu()
{
	cout<<"--------------------設備管理---------------------"<<endl;
	cout<<"                 a  添加設備"<<endl; 
	cout<<"                 d  刪除設備"<<endl; 
	cout<<"                 r  申請設備"<<endl; 
	cout<<"                 c  回收設備"<<endl;
	cout<<"                 s  設備狀態查看"<<endl;
        cout<<"                 p  磁盤調度"<<endl;
	cout<<"                 o  退出程序"<<endl;
	cout<<"-------------------------------------------------"<<endl;
}
  • 設備狀態查看
void play()
{
	cout<<"    "<<"設備名稱"<<"   "<<"類型"<<"    "<<"控制器"<<"    "<<"通道"<<endl;
	for(int i=0;i<e;i++)
		cout<<"       "<<d[i]->sdt->name<<"        "<<d[i]->sdt->type<<"        "<<d[i]->coct->name<<"       "<<d[i]->coct->chct->name<<endl;

}
  • main函數,功能調用
int main()
{
	init();
	menu();
	cout<<"請選擇:"<<endl;
	char c;
    cin>>c;
	while(c)
	{
	switch(c)
		{
	    case 'a':
			add();
		    break;
	    case 'd':
			del();
		    break;
	    case 'r':
			require();
		    break;
    	case 'c':
			callback();
     		break;
        case 's':
			play();
        	break;
        case 'p':
            cipantiaodu();
            break;
        case 'o':
			exit(1);
    	default:
	    	cout<<"輸入錯誤! ";
		    break;
		}
    	cout<<"請選擇:"<<endl;
        cin>>c;
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM