1. 程式人生 > >作業系統--用JavaScript實現銀行家演算法

作業系統--用JavaScript實現銀行家演算法

var num_process; //記錄程序數
var num_resource;//記錄資源數
var max = new Array();//最大資源數
var need = new Array();//資源需求數
var work = new Array();//資源可用數
var work2 = new Array();//用於記錄每次程序呼叫的Work數
var available = new Array();//可利用資源數
var allocation = new Array();//已分配資源
var request = new Array();//請求資源數
var finish = new Array();//是否已完成
var safe = new Array();//安全序列
var fg = false;    //更新Available標誌
var o = 0;

//動態建立表格(第一個表格)
function CreateTable(){
	var tabletext = "";
	tabletext = "</br>系統資源的總數依次是:";
	for(i=0;i<num_resource;i++)
	{
		tabletext += " " + available[i] + "    ";
	}
	tabletext += "<p><p/><hr/>";
	tabletext += "請輸入各個程序的最大需求數(Max)和已分配數(Allocation)</br>";
	tabletext += "<table border=1 cellspacing=1 width=80% style='text-align:center;border-collapse:collapse;border-width:thin;border-style:solid;margin:0;'><tr><td>資源</td><td colspan="+num_resource+">Max</td><td colspan="+num_resource+">Allocation</td colspan="+num_resource+"><td colspan="+num_resource+">Need</td colspan="+num_resource+"><td colspan="+num_resource+">Available</td></tr>";
	tabletext += "<tr>"+"<td>程序</td>";
	for(i=0;i<4;i++)
	{
		for(j=0;j<num_resource;j++)
		{
			tabletext += "<td>"+String.fromCharCode((65+j))+"</td>";
		}
	}
	tabletext += "</tr>";
    for(i=0;i<num_process;i++)
    {
        tabletext += "<tr><td>P"+i+"</td>";
        for(j=0;j<4;j++)
        {
            for(x=0;x<num_resource;x++)
            {
                tabletext += "<td class='numtd'><input type=text id=e"+i+j+x+" class= 'numtext'"; 
                if(j==2||j==3)
                {
                	tabletext += " readonly=\"readonly\" "
                }
                tabletext += "></td>";
            }  
        }
        tabletext += "</tr>";
    }
    tabletext += "</table>";
	document.getElementById("d_table").innerHTML += tabletext;
}

//建立安全表格
function chickSafeTable(){
	var tabletext = "";
	tabletext = "<table border=1 cellspacing=1 width=80% style='text-align:center;border-collapse:collapse;border-width:thin;border-style:solid;margin:0;'><tr><td>資源</td><td colspan="+num_resource+">Work</td><td colspan="+num_resource+">Need</td colspan="+num_resource+"><td colspan="+num_resource+">Allocation</td colspan="+num_resource+"><td colspan="+num_resource+">Work+Allocation</td colspan="+num_resource+"><td>Finish</td></tr>";
	tabletext += "<tr>"+"<td>程序</td>";
	for(i=0;i<4;i++)
	{
		for(j=0;j<num_resource;j++)
		{
			tabletext += "<td>"+String.fromCharCode((65+j))+"</td>";
		}
	}
	tabletext += "</tr>";
	for(i=0;i<num_process;i++)
    {
        tabletext += "<tr><td>P"+safe[i]+"</td>";
        for(j=0;j<5;j++)
        {
            for(x=0;x<num_resource;x++)
            {
            	if(j==4&&x==0)
            	{
            		tabletext += "<td id=t"+i+j+x+" class='outtable'></td>"; 
            		break;
            	}
            	else
            	{
            		tabletext += "<td id=t"+i+j+x+" class='outtable'></td>"; 
            	}
            }  
        }
        tabletext += "</tr>";
    }
    tabletext += "</table>";
    document.getElementById("output2").innerHTML += tabletext;
    updataOfSafeList();
}

//更新安全表格(第二個表格)
function updataOfSafeList(){
	//Work
	for(i=0;i<num_process;i++)
    {
        for(j=0;j<num_resource;j++)
        {
            document.getElementById("t"+i+"0"+j).innerHTML = work2[i][j]; 
        }  
    }
    //Need
	for(i=0;i<num_process;i++)
    {
        for(j=0;j<num_resource;j++)
        {
            document.getElementById("t"+i+"1"+j).innerHTML = need[parseInt(safe[i])][j];
        }  
    }
    //Allocation
    for(i=0;i<num_process;i++)
    {
        for(j=0;j<num_resource;j++)
        {
            document.getElementById("t"+i+"2"+j).innerHTML = allocation[parseInt(safe[i])][j];
        }  
    }
    //Work+Allocation
    for(i=0;i<num_process;i++)
    {
        for(j=0;j<num_resource;j++)
        {
            document.getElementById("t"+i+"3"+j).innerHTML = work2[i][j]+allocation[safe[i]][j];
        }  
    }
    //Finish
    for(i=0;i<num_process;i++)
    {
        document.getElementById("t"+i+"4"+"0").innerHTML = finish[safe[i]];
    }
}

//點選第一個按鈕
function onClickOK(){
	document.getElementById("input").style.display = "none";
	num_process = parseInt(document.getElementById("t_process").value);
	num_resource = parseInt(document.getElementById("t_resource").value);
	ChickNull(num_process,"請輸入程序數:");
	ChickNull(num_resource,"請輸入資源數:");
	if(isNaN(num_process&&num_resource))
	{
		alert("請輸入數字!");
		return;
	}
	alert(num_process+"個程序"+num_resource+"個資源");
	for(i=0;i<num_resource;i++)
	{
		available[i] = window.prompt("第"+(i+1)+"個資源總數:");
		ChickNull(available[i],"請輸入資源總數:");
		if(isNaN(available[i]))
		{
			alert("請輸入數字!");
			return;
		}
	}
	CreateTable();
	document.getElementById("d_display").style.display = "";
}

//點選第二個按鈕
function onClickOK2()
{
	GetInfo();
	ChickSequence();
	PrintSequence("outputlist");
}

//獲得填充資料
function GetInfo()
{
    //獲取最大資源數
    for(i=0;i<num_process;i++)
    {
        max[i]=new Array();
        for(j=0;j<num_resource;j++)
        {
            max[i][j]=parseInt(document.getElementById("e"+i+"0"+j).value);
            ChickNull(max[i][j],"請輸入最大資源數:");
			if(isNaN(max[i][j]))
			{
				alert("請輸入數字!");
				return;
			}
        }  
    }
       
    //獲取已分配資源數
    for(i=0;i<num_process;i++)
    {
        allocation[i]=new Array();
        for(j=0;j<num_resource;j++)
        {
            allocation[i][j]=parseInt(document.getElementById("e"+i+"1"+j).value);
            ChickNull(allocation[i][j],"請輸入已分配資源數:");
			if(isNaN(allocation[i][j]))
			{
				alert("請輸入數字!");
				return;
			}
        }  
    }
}

//得到並填充Need
function GetNeed()
{
    //計算各程序對個資源的需求量
    for(i = 0; i < num_process; i ++)
    {
        need[i]=new Array();
        for(j = 0; j < num_resource; j ++)
        {
            need[i][j] = max[i][j] - allocation[i][j];
        }
    }
    //填充Need
    for(i=0;i<num_process;i++)
    {
        for(j=0;j<num_resource;j++)
        {
            document.getElementById("e"+i+"2"+j).value = need[i][j];
        }  
    }
}

//得到Work
function GetWork()
{
    for(j=0;j<num_resource;j++)
    {
        work[j]=available[j];
    }
}

//得到並填充Available
function GetAvailable(fg)
{
	//計算Available
	if(!fg)
	{
		for(i=0;i<num_resource;i++)
		{
			for(j=0;j<num_process;j++)
			{
				available[i] -= allocation[j][i];
				if(available[i]<0)
				{
					alert("請求失敗!無可利用資源");
					return false;
				}
			}
		}
	}
	else
	{
		if(available[i]<0)
		{
			alert("請求失敗!無可利用資源");
			return false;
		}
		else
		{}
	}
	//填充Available
	for(i=0;i<num_resource;i++)
    {
        document.getElementById("e"+0+"3"+i).value = available[i];  
    }
    return true;
}

//新請求資源
function Banker()
{
	fg = true;
	var v1 = parseInt(window.prompt("請輸入第幾個程序請求資源"));
	for(i=0;i<num_process;i++)
	{
		request[i] = new Array();
	}
	for(j=0;j<num_resource;j++)
	{
		request[v1-1][j] = window.prompt("程序P"+(v1-1)+"請求資源"+String.fromCharCode((65+j))+"數量:");
		ChickNull(request[v1-1][j],"請輸入程序所請求資源數:");
		if(isNaN(request[v1-1][j]))
		{
			alert("請輸入數字!");
			return;
		}
	}
	for(j=0;j<num_resource;j++)
	{
		if(request[v1-1][j]>need[v1-1][j])
		{
			alert("請求資源數大於所需最大值,失敗!");
			return;
		}
		
		else if(request[v1-1][j]>available[j])
		{
			alert("請求資源數大於可利用資源量,請等待!");
			return;
		}
		else
		{
			available[j] -= request[v1-1][j];
			var v2 = parseInt(allocation[v1-1][j]);
			var v3 = parseInt(request[v1-1][j]);
			allocation[v1-1][j] = v2+v3;
			need[v1-1][j] -= request[v1-1][j];
		}
	}
	ChickSequence();
	PrintSequence("output2");
}

//獲得安全序列
function ChickSequence()
{
	GetNeed();
	GetAvailable(fg);
	GetWork();
	//初始化work2
	for(i=0;i<(num_process+1);i++)
	{
		work2[i] = new Array();
	}
	for(i=0;i<num_resource;i++)
	{
		work2[0][i] = work[i];
	}
	//初始化finish
	for(i=0;i<num_process;i++)
	{
		finish[i] = false;
	}
	o = 0;
	//演算法核心!!!
	while(o < num_process)
    {
        flag = false;
        for(i = 0; i < num_process; i ++)
        {
            if(finish[i])
            continue;
            for( j = 0; j < num_resource; j ++)
            {
                if(need[i][j] > work[j])
                break;
            }
            if(j == num_resource)
            {
                flag = true;
                safe[o] = i;
                o++;
                finish[i] = true;
                for(k = 0; k < num_resource; k ++)
                {
                	work[k] += allocation[i][k];
                	work2[o][k] = work[k];
                }             
            }
        }
        if(!flag)
        break;
    }
}

//輸出安全序列
function PrintSequence(id)
{
    if(o == num_process)
    {
        html="<hr/>該資源是安全的;安全序列為:";
        for(i=0;i<o;i ++)
        {
            html+="P"+safe[i];
            if(i<o-1)
            html+="->";
        }     
    }
    else 
    {
    	html="<hr/>對不起,該資源狀態不安全!";
    	document.getElementById(id).innerHTML = html;
    	return;
    }
    document.getElementById(id).innerHTML = html;
    chickSafeTable();
}

//判斷輸入是否為空
function ChickNull(text,warning)
{
	if(text.length==0)
	{
	    alert(warning);
		return false; 
	}
  else if (/\s/.test(text))
  {
  		alert("輸入不能為空格!");
		return false; 
  }
	return true;
}

3.css部分

body{
	background-image: url(../img/bg2.jpg);
	background-size:100%;
	background-color:#000000;
	font-family:微軟雅黑;
	font-size: 20px;
	color: #FFFFFF;
}

h1{
	font-family:微軟雅黑;
	font-size:50px;
	color:#FFFFFF;
}

.numtext{
	border: 0px;
	width: 90%;
	height: 100%;
	text-align: center;
	background: none;
	color: #FFFFFF;
}

.numtd{

}

#input{
	margin-top: 0px;
	margin-right: auto;
	margin-bottom: 0px;
	margin-left: auto;
}

 #b_ok{
 	background-color: #87CEEB;
 	color:#FFFFFF;font-family:微軟雅黑;
 	font-weight: 900;
 	font-size: 15px;
 	padding:3px 5px;
 	border-radius:100% ;
 	cursor:pointer;
 	width:100px;
 	height:100px;
 }
 
 #b_ok2,#b_ok3{
 	background-color: #87CEEB;
 	color:#FFFFFF;font-family:微軟雅黑;
 	font-weight: 900;
 	font-size: 15px;
 	padding:3px 5px;
 	border-radius:15px ;
 	cursor:pointer;
 	width:100px;
 	height:30px;
 }

#t_process,#t_resource{
	text-align: center;
	background: none;
	color: #FFFFFF;
}