Professional Documents
Culture Documents
ĐỒ ÁN MÔN HỌC
NGUYÊN LÝ HỆ ĐIỀU HÀNH
Đà nẵng, 01/2010
LỜI CẢM ƠN
Những kiến thức cơ bản cũng như nâng cao về hệ điều hành, nắm bắt được
nguyên tắc hoạt động. Nguyên lý hệ điều hành là học phần rất quan trọng và bắt buộc
đối với tất cả sinh viên chuyên ngành công nghệ thông tin. Nguyên lý hệ điều hành
cung cấp cho sinh viên động cơ bản của hệ điều hành trên máy tính.
Hệ điều hành được xem là thành phần trung gian hay là cầu nối cho sự giao
tiếp của người sử dụng và máy tính. Thông qua hệ điều hành người sử dụng dễ dàng
làm việc và khai thác hiệu quả thiết bị phần cứng máy tính, quản lý phần mềm ứng
dụng. Người sử dụng chỉ cần thao tác các lệnh, các sự kiện và chờ các tiến trình của hệ
điều hành thực hiện.
Với một Hệ điều hành có tiềm năng như thế, chúng ta phải có sự nghiên cứu,
hiểu biết về nó, để có thể nắm bắt tốt về các khái niệm chuyên ngành về Hệ điều hành.
Em xin cảm ơn sự hướng dẫn tận tình của thầy th.S. Nguyễn Văn Nguyên đã
giúp em hoàn thành đề tài này.
LỜI MỞ ĐẦU
Nếu không có phần mềm, máy tính chỉ là một thiết bị điện tử thông thường.
Với sự hỗ trợ của phần mềm, máy tính có thể lưu trữ, xử lý thông tin và người sử dụng
có thể gọi lại được thông tin này. Phần mềm máy tính có thể chia thành nhiều loại:
chương trình hệ thống, quản lý sự hoạt động của chính máy tính. Chương trình ứng
dụng, giải quyết các vấn đề liên quan đến việc sử dụng và khai thác máy tính của
người sử dụng. Hệ điều hành thuộc nhóm các chương trình hệ thống và nó là một
chương trình hệ thống quan trọng nhất đối với máy tính và cả người sử dụng. Hệ điều
hành điều khiển tất cả các tài nguyên của máy tính và cung cấp một môi trường thuận
lợi để các chương trình ứng dụng do người sử dụng viết ra có thể chạy được trên máy
tính.
Một máy tính hiện đại có thể bao gồm: một hoặc nhiều processor, bộ nhớ
chính, clocks, đĩa, giao diện mạng, và các thiết bị vào/ra khác. Tất cả nó tạo thành một
hệ thống phức tạp. Để viết các chương trình để theo dõi tất cả các thành phần của máy
tính và sử dụng chúng một cách hiệu quả, người lập trình phải biết processor thực hiện
chương trình như thế nào, bộ nhớ lưu trữ thông tin như thế nào, các thiết bị đĩa làm
việc (ghi/đọc) như thế nào, lỗi nào có thể xảy ra khi đọc một block đĩa, … đây là
những công việc rất khó khăn và quá khó đối với người lập trình. Nhưng rất may cho
cả người lập trình ứng dụng và người sử dụng là những công việc trên đã được hệ điều
hành hỗ trợ nên họ không cần quan tâm đến nữa. chúng ta cần tiềm hiểu về hệ điều
hành để có một cái nhìn tổng quan về những gì liên quan đến việc thiết kế cài đặt cũng
như chức năng của hệ điều hành để hệ điều hành đạt được mục tiêu: Giúp người sử
dụng khai thác máy tính dễ dàng và chương trình của người sử dụng có thể chạy được
trên máy tính.
"Bài toán bữa tối của các triết gia" (Dining Philosophers), một bài toán kinh
điển về tương tranh và chia sẻ tài nguyên. Việc nghiên cứu bài toán sẽ cho chúng ta
hiểu rõ hơn về khía cạnh này của hệ điều hành.
PHỤ LỤC
CHƯƠNG I BÀI TOÁN....................................................................................6
I.1 Đề tài........................................................................................................6
I.2 Mô tả vấn đề.............................................................................................6
I.3 Yêu cầu bài toán.......................................................................................6
CHƯƠNG II CƠ SỞ LÝ THUYẾT...................................................................7
II.1 Tiến trình (proccess)...............................................................................7
II.1.1 Khái niệm........................................................................................7
II.1.2 Định nghĩa tiến trình........................................................................7
II.1.3 Các loại tiến trình.............................................................................7
II.1.4 Tuyến (Thred)..................................................................................7
II.2 Tài nguyên găng và đoạn găng................................................................8
II.2.1 Tài nguyên găng (Critical Resource)...............................................8
II.2.2 Đoạn găng (Critical Section)............................................................9
II.2.3 Yêu cầu đối với đoạn găng..............................................................9
II.3 Giải pháp Semaphore..............................................................................9
II.4 Deadlock...............................................................................................10
II.4.1 Giới thiệu vấn đề............................................................................10
II.4.2 Điều kiện hình thành tắt nghẽn......................................................11
II.4.3 Ngăn chặn tắc nghẽn (Deadlock Prevention).................................11
CHƯƠNG III CÁCH GIẢI QUYẾT BÀI TOÁN............................................12
III.1 Quản lý vùng găng...............................................................................12
III.2 Giải pháp xử lý deadlock.....................................................................14
III.3 Chương trình........................................................................................14
III.3.1 Class Philosopher.........................................................................15
III.3.2 Class Chopstick............................................................................16
III.3.3 Class Diner...................................................................................16
III.3.4 Class PhilCanvas..........................................................................16
CHƯƠNG IV KẾT QUẢ CHƯƠNG TRÌNH..................................................17
IV.1.1 Chương trình tạm dừng................................................................17
IV.1.2 Chương trình được reset...............................................................18
CHƯƠNG V KẾT LUẬN...............................................................................19
V.1.1 Đạt được........................................................................................19
V.1.2 Chưa đạt........................................................................................19
I.1 Đề tài
Viết chương trình giải quyết bài toán “Năm triết gia ăn tối”. Chương trình tạo
ra năm quá trình con mô phỏng hoạt động của năm triết gia. Sử dụng Semaphore để
đồng bộ hoạt động của năm triết gia này.
I.2 Mô tả vấn đề
Đây là bài toán cổ điển về hệ điều hành. Bài toán bữa tối của các triết gia được
đưa ra bởi nhà toán học E. W. Dijkstra. Bài toán được mô tả như sau :
Có năm triết gia cùng ngồi ăn tối quanh một chiếc bàn tròn, trước mặt mỗi
người có một đĩa mì Ý, giữa 2 triết gia thì có một chiếc nĩa.
Mỗi triết gia dành toàn bộ thời gian để suy nghĩ hoặc ăn khi đói.
Mỗi triết gia chỉ có thể ăn khi có được 2 chiếc nĩa bên cạnh mình.
Đói : một triết gia có thể chết đói nếu ông ta không có cách nào để ăn được
Tắc nghẽn : các triết gia phải đợi lẫn nhau nên không có ai ăn được.
CHƯƠNG II CƠ SỞ LÝ THUYẾT
tiến trình, cơ chế liên lạc giữa các tuyến đơn giản và hiệu quả hơn cơ chế liên lạc giữa
các tiến trình với nhau ( nếu hệ điều hành của bạn chạy trên phần cứng nhiều bộ xử lí
thì tuyến thực sự chạy song song chứ không phải giả lập kiểu xoay vòng ).
Ưu điểm của sử dụng tuyến trong tiến trình đơn giản hơn lập trình tuần tự.
Nhiều thao tác xuất nhập hoặc hiển thị dữ liệu có thể tách rời và phân cho các tuyến
chạy độc lập thực thi. Ví dụ trong môi trường đồ họa, khi bạn copy một file có kích
thước lớn, chương trình sẽ được thiết kế sao cho một tuyến thực hiện đọc ghi dữ liệu
từ đĩa, tuyến khác sẽ đảm trách việc hiển thị phần trăm hoàn thành công việc cho
người dùng theo dõi tiến độ.
Đối với hệ điều hành chi phí để chuyển đổi giữa ngữ cảnh của tiến trình cao và
chậm hơn chi phí chuyển đổi ngữ cảnh dành cho tuyến ( với tiến trình hệ điều hành
phải cất thông số môi trường, thanh ghi trạng thái, hoán đổi vùng nhớ…)
Tuy nhiên, điểm yếu của việc dùng tuyến đó là khả năng đổ vở của một tuyến
sẽ ảnh hưởng đến tất cả các tuyến khác và toàn bộ tiến trình đang hoạt động. Lí do là
các tuyến dùng chung vùng nhớ và không gian địa chỉ của tiến trình. Ngược lại, một
tiến trình bị đổ vỡ luôn được hệ điều hành cô lập hoàn toàn không gây ảnh hưởng đến
các tiến trình khác. Tiến trình có thể chạy trên nhiều máy khác nhau trong khi tuyến
chỉ được thực thi trên một máy và trong một tiến trình.
Mỗi tiến trình ngay sau khi ra khỏi đoạn găng phải gọi Up để kiểm tra xem có
tiến trình nào đang đợi trong hàng đợi hay không, nếu có thì đưa tiến trình trong hàng
đợi vào đoạn găng. Khi tiến trình gọi Up thì hệ thống sẽ thực hiện.
Ở đây chúng ta cần lưu ý rằng: Down và Up là các thủ tục của hệ điều hành,
nên hệ điều hành đã cài đặt cơ chế độc quyền cho nó, tức là các lệnh bên trong nó
không thể tách rời nhau.
II.4 Deadlock
Nếu tài nguyên chung (Chopstick) đang được sử dụng thì triết gia phải đợi
(wait) cho đến khi tài nguyên được giải phóng, lúc đó triết gia sử dụng tài nguyên này
đồng thời thiết lập taken = true để khóa các tiến trình khác. Như vậy biến taken đóng
vai trò khóa vùng tài nguyên dùng chung khi nó đang được sử dụng bởi một tiến trình.
Chương trình tạo ra 5 tiến trình tương ứng với 5 triết gia và 5 tài nguyên dùng
chung tương ứng 5 chopsticks
Phương thức Wait() và Signal() được xây dựng để quản lí tiến trình ra vào
vùng găng. Với cách xây dựng như trên thì 2 tiến trình cạnh nhau có số thứ tự chẳn lẽ
khác nhau sẽ có thứ tự lấy các chopstick theo thứ tự khác nhau.
Khởi động lại các tiến trình được tạm dừng, reset lại băng thông báo trạng thái.
[1] Đặng Vũ Tùng, Giáo trình Nguyên Lý Hệ Điều Hành, NXB Hà Nội(2005)
[2] http://www.scribd.com/doc/7221635/H-iu-hanh?autodown=pdf
[3] Đồ án mẫu khóa 05
PHỤ LỤC
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
PhilCanvas display;
Thread[] phil= new Thread[PhilCanvas.NUMPHILS];
Chopstick[] chopstick = new Chopstick[PhilCanvas.NUMPHILS];
JScrollBar slider;
JButton restart;
JButton freeze;
TextArea txtMes;
public void init() {
setLayout(new BorderLayout());
display = new PhilCanvas(this);
display.setSize(300,320);
add("Center",display);
slider = new JScrollBar(Scrollbar.HORIZONTAL, 50, 5, 0, 100);
restart = new JButton("Restart");
restart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (display.deadlocked()) {
stop();
slider.setValue(50);
start();
}
display.thaw();
}
});
freeze = new JButton("Freeze");
freeze.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
display.freeze();
}
});
else{
view.setPhil(identity,view.HUNGRY);
left.get();
//gotright chopstick
view.setPhil(identity,view.GOTLEFT);
sleep(500);
right.get();
}
}
class Chopstick {
notify();
}
Diners controller;
Image offscreen;
Dimension offscreensize;
Graphics offgraphics;
static final int NUMPHILS = 5;
static final int THINKING = 0;
static final int HUNGRY = 1;
static final int GOTRIGHT = 2;
static final int EATING =3;
static final int GOTLEFT = 4;
Image[] imgs = new Image[5];
AffineTransform [] philPlace = new AffineTransform[NUMPHILS];
int [] state = new int [NUMPHILS];
double [] chopX = new double[NUMPHILS];
double [] chopY = new double[NUMPHILS];
double [] disX = new double[NUMPHILS];
double [] disY = new double[NUMPHILS];
boolean[] untable= new boolean[NUMPHILS];
boolean frozen = false;
String Message = "";
PhilCanvas(Diners controller) {
super();
this.controller = controller;
MediaTracker mt;
mt = new MediaTracker(this);
imgs[0] = controller.getImage(controller.getDocumentBase(),
"image/thinking.gif");
mt.addImage(imgs[0], 0);
imgs[1] = controller.getImage(controller.getDocumentBase(),
"image/hungry.gif");
mt.addImage(imgs[1], 1);
imgs[2] = controller.getImage(controller.getDocumentBase(),
"image/gotright.gif");
mt.addImage(imgs[2], 2);
imgs[3] = controller.getImage(controller.getDocumentBase(),
"image/eating.gif");
mt.addImage(imgs[3], 3);
imgs[4] = controller.getImage(controller.getDocumentBase(),
"image/gotleft.gif");
mt.addImage(imgs[4], 4);
try {
mt.waitForID(0);
mt.waitForID(1);
mt.waitForID(2);
mt.waitForID(3);
mt.waitForID(4);
} catch (java.lang.InterruptedException e) {
System.out.println("Couldn't load one of the images");
}
initPlacing();
}
void backdrop() {
Dimension d = getSize();
if ((offscreen == null) || (d.width != offscreensize.width)
|| (d.height != offscreensize.height)) {
offscreen = createImage(d.width, d.height);
offscreensize = d;
offgraphics = offscreen.getGraphics();
offgraphics.setFont(new Font("Helvetica",Font.BOLD,18));
Graphics2D g2D = (Graphics2D) offgraphics;
g2D.translate(d.width/2, d.height/2);
}
offgraphics.setColor(Color.WHITE);
offgraphics.fillRect(-d.width/2, -d.height/2, d.width, d.height);
}
void drawtable() {
offgraphics.setColor(Color.red);
offgraphics.fillOval(-80,-80,160,160);
offgraphics.setColor(Color.black);
for(int i=0; i<NUMPHILS; i++) {
if(untable[i]){
offgraphics.setColor(Color.black);
offgraphics.fillRect((int)chopX[i],(int)chopY[i],5,30);
}
offgraphics.setColor(Color.black);
offgraphics.drawString(String.valueOf(i),(int)disX[i],(int)disY[i]);
offgraphics.setColor(Color.WHITE);
offgraphics.fillOval((int)disX[i],(int)disY[i],25,25);
}
}
boolean deadlocked(){
int i=0;
while(i<NUMPHILS && state[i]==GOTRIGHT) ++i;
return i==NUMPHILS;
}
void initPlacing() {