Tải bản đầy đủ (.docx) (14 trang)

BÀI tập môn học NGUYÊN lý hệ điều HÀNH VIẾT CHƯƠNG TRÌNH mô PHỎNG QUÁ TRÌNH ĐỒNG bộ TIẾN TRÌNH THEO THEO THUẬT TOÁN 5 TRIẾT GIA ăn tối BẰNG NGÔN NGỮ JAVA

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (138.21 KB, 14 trang )

HỌC VIỆN KỸ THUẬT MẬT MÃ
KHOA CỒNG NGHỆ THÔNG TIN

BÀI TẬP MƠN HỌC NGUN LÝ HỆ ĐIỀU HÀNH
VIẾT CHƯƠNG TRÌNH MƠ PHỎNG Q TRÌNH ĐỒNG BỘ TIẾN
TRÌNH THEO THEO THUẬT TỐN 5 TRIẾT GIA ĂN TỐI BẰNG
NGƠN NGỮ JAVA

Ngành: An tồn thơng tin

Sinh viên thực hiện:
Nguyễn Văn Hiệp
Phạm Cơng Hưởng
Nguyễn Anh Tuấn
Lớp: AT16C0405
Người hướng dẫn:
TS. Nguyễn Đào Trường
Khoa Công nghệ thông tin - Học viện Kỹ thuật mật mã


Hà Nội, 2022


NHẬN XÉT VÀ CHO ĐIỂM CỦA GIÁO VIÊN


LỜI NĨI ĐẦ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 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 tinh hiện đại có thể bao gồm: một hoặc nhiều processor, bộ 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 (đọc/ghi) 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à q q 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 cái đấy nữa. Chúng ta cần
tìm hiểu về hệ điều hành đề có một cái nhìn tổng quát về những gì liên quan đến
việc
thiết kế cài đặt cũgn 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 một cách 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 tố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ề khia cạnh này của hệ thống.


CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
I, Tiến trình(processes).
1, Khái niệm:
- Tiến trình là một bộ phận của một chương trình thực đang thực hiện,

đơn vị thực hiện tiến trình là processer.
- Vì tiến trình là một bộ phận của chương trình nên tương tự như chương
trình tiến trình cũng sở hữu một con trỏ lệnh, một con trỏ stack, một tập các
thanh
ghi, một không gian địa chỉ trong bộ nhớ chính và tất cả các thơng tin cần
thiết
khác
để tiến trình có thể hoạt động được.
2, Các loại tiến trình:
- Các tiến trình trong hệ thống chia làm hai loại: tiến trình tuần tự và
tiến trình song song.
+ Tiến trình tuần tự là các tiến trình mà điểm khởi tạo của nó là
điểm kết thúc của tiến trình trước đó.
+ Tiến trình song song là các tiến trình mà điểm khởi tạo của
tiến
trình này nằm ở thân của các tiến trình khác, thức là có thể khởi tạo một tiến trình
mới khi các tiến trình đó chưa kết thúc.
II, Luồng(Thread).
Luồng là thành phần của tiến trình sở hữu ngăn xếp và thực thi độc lập ngay
trong mã lệnh của tiến trình. Nếu như hệ điều hành có nhiều tiến trình thì trong mỗi
tiến trình bạn có thể tạo ra nhiều tuyến hoạt động song song trong hệ điều hành. Ưu
điểm của tuyến là chúng hoạt động trong cùng một không gian địa chỉ của tiến
trình.
Tập hợp một nhóm các tuyến có thể sử dụng chung biến toàn cục, vùng nhớ Heap,
bảng mơ tả íìle... của tiến trình, cơ chế liên lạc giữa 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.
Ưu điểm của việc sử dụng luồng trong tiến trìnhh đơ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.
III,Giải pháp Semaphore.

Semaphore là một dóng góp quan trọng của nhà tốn học E. W. Dijktra. Có


thể xem Semaphore như là một mở rộng của Mutex locks.
Semaphore S là một biến tài nguyên, khởi gán bằng một giá trị khơng âm, đó
là khả năng phục vụ của tài nguyên tương ứng với nó.
Ứng với S có một hàng đợi F(s) để lưu các tiến trình đang bị blocked trên S.


Chỉ có hai thao tác Down và Up được tác động đến Semaphore S. Down
giảm
S xuống một đơn vị, Up tăng S lên một đơn vị.
Ở đâ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.
IV, Deadlock
- Deadlock là một trạng thái mà ở đó một tập các tiến trình bị chặn vì mỗi tiến
trình đang chiếm giữ tài nguyên và chờ đợi được cấp phát tài nguyên khác
được
giữ
bởi tiến trình khác. Nói cách khác, mỗi tiến trình trong hệ thống đang chờ để
được
cấp phát tài nguyên đang bị chiếm giữ bởi tài ngun khác. Nếu tài ngun
đó
khơng
được giải phóng để tiến trình khác có thể sử dụng, thì tiến trình đang chờ lấy
tài
nguyên sẽ chờ mãi, chờ mãi dẫn đến khoá chết (Deadlock)
- Các điều kiện phát sinh Deadlock:
+ Loại từ tương hỗ (Mutual Exclusion): tại một thời điểm, tài nguyên

không thể chia sẻ được cho hệ thống cấp phát cho một tiến trình duy nhất. Tiến
trình
khác khơng thể sử dụng cho đến khi tài nguyên được giải phóng.
+ Giữ và chờ (hold and wait): Mỗi tiến trình trong tập hợp tiến trình
đang giữ một tài nguyên và chờ đợi để được cấp phát một tài nguyên mới.
+ Khơng có quyền ưu tiên (No Preemption): Một tiến trình không thể
ciếm giữ tài nguyên cho đến khi tài nguyên đó được giải phóng bởi tiến trình đang
sử dụng nó.
+ Tồn tại chu kì chờ (Circular Wait): Các tiến trình giữ một tài nguyên
và chờ nhận một tài nguyên khác bởi tiến trình kahsc. Chúng nối đi nhau tạo
thành
vịng trịn. Chờ vô tận.


CHƯƠNG 2: MƠ TẢ BÀI TỐN
I, Đề bài:
Viết chương trình mơ phỏng q trình đồng bộ tiến trình (điều độ) theo thuật
tốn 5 triết gia ăn tối bằng ngơn ngữ Java.
II, Mơ tả bài tốn:
Đây là một bài tố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
đưuocj đưa ra bời nhà toán học E. W.Dijkstra. Bài tốn được mơ tả như sau: Có
năm
triết gia cùng ngồi ăn quanh một chiếc bàn tròn, trước mặt mỗi người có một đĩa đồ
ăn, mỗi người có một đĩa, giữa hai triết gia thì có một chiếc đũa. Bài toán được phát
biểu như sau: “ khi một triết gia suy nghĩ, ông ta không thể giao tiếp với các triết
gia
khác. Thỉnh thoảng, một triết gia cảm thấy đói và cố gắng chọn 2 chiếc đũa gần
nhất(
đũa trái và đũa phải). Một triết gia chỉ có thể chỉ lấy một chiếc đũa tại một thời
điểm.

Chú ý, ông ta không thể lấy chiếc đũa mà nó đang được dùng bởi người bên cạnh.
Khi một triết gia đối và có hai chiếc đũa cùng một lúc, ông ta ăn mà không đặt đũa
xuống. Khi triết gia ăn xong, ông ta đặt đũa xuống và bắt đầu suy nghĩ tiếp”.
III,Yêu cầu:
- Tìm cách để khơng ai chết đói.
- Bài tốn đặt ra vấn đề “đồng bộ giữa các tiến trình”, giải quyết vấn đề tắc
nghẽn có thể xảy ra.


CHƯƠNG 3: CÁCH GIẢI QUYẾT BÀI TỐN
I, Mơ tả hướng giải quyết.
Để giải quyết bài tốn, thì trong phần này, ta sẽ sử dụng thuật tốn
Semaphore.
Và sử dụng tính chất hoạt động song song của đa luồng (Thread).
II, Giải thích code và kết quả.
1, Class Fork (đũa):
statĩc class Fork {
public Semaphore mutex = new Semaphữ
void grab() {
try {

mutex.acquire()j

}
catch (Exception e) {
e.printStackTrace(System.out);

}
}
void release() {

mutex.release()■

}
boolean isFree() {
return mutex.availablePermitsO > 0j

}
}
- Với class này, chúng ta áp dụng thuật toán Semaphore để đánh dấu trạng thái
của
những chiếc đũa trong bài toán. Những chiếc đũa ban đầu sẽ có giá trị là 1. Ở
giá
trị
này, thì nó coi là đang khơng được sử dụng.
- Khi mà chiếc đũa đang được sử dụng, với phương thức acquire(), sẽ gán cho
chiếc
đũa đấy giá trị là 0 - hay là đang trong trạng thái sử dụng.
- Khi mà sử dụng xong (Hết sleep time) thì phương thức release() sẽ trả lại cho
chiếc


đũa đấy giá trị là 1.
- Ở đây, ta sẽ cho thêm phương thức isFree(), phương thức này sẽ giúp kiểm
tra
trạng
thái của chiếc đũa.
2, Class Philosopher


static class Philosopher extends Thread {

public int number;
public Fork leftFork;
public Fork rightFork;
Philosopher(int num, Fork left, Fork right) {
number = num;
leftFork = lt;
rightFork = right;
}
public void run(){
System.out.println("Xin chão! Tịi lã nhã triết gia số " + number);
int think = 0;
while (true) {
leftFork.grab();
System.out.println("Nhà triểt gia số " + number + ” láy đũa trái.1');
rightFork.grab();
System.out.println("Nhà triết gia sổ " + number + " láy đũa phải.");
think = 1;
eat();
leftFork.release();
System.out.println("Nhà triết gia số " + number + " nhả đũa trái.");
rightFork.release();
System.out.println("Nhà triết gia số " + number + " nhả đũa phải.");
if (think == 1) 0
System.out.println("Nhà triết gia sổ " + number + " đang suy nghĩ!1');
}

}|

}
//

void eat() {
try {
int sleepTime = ThreadLocalRandom.currento.nextlnt(0, 1000);
System.out.println("Nhà triết gia số " + number + " ăn trong " + sleepTime);
Thread.steep(sleepTime);
}
catch (Exception e) {
e.printStackTrace(System.out);
}
1

- Với class Philosopher, ta sẽ kế thừa class Thread để giúp cho class này sử
dụng cơ
chế đa luồng của Thread.
- Đầu tiên, sẽ có 3 thuộc tính, đó là number: số thứ tự của các nhà triết gia,
leftFork
và rightFork: là đũa trái, đũa phải của các triết gia tương ứng.
- Tiếp theo, sẽ có một hàm khởi tạo của class này.
- Các triết gia có các hành động là: tham gia vào bữa ăn, lấy đũa trái, lấy đũa
phải,
suy nghĩ và ăn.
3, Main:


public static void main(string argv[]) {
System.out.println("Giái quyết vãn đề bữa ăn của các nhà triết gia.");
for (int i = 0; i < phỉLosophersNumber; i++) {
/orfes[i] = new Fork();

for (int i = 0; i < phiLosophersNumber' Ỉ++) {

phỉLosophers[i] = new Philosopheríi, /orfes[i]j forks[(i + 1) % phỉLosophersNumber]);
phỉLosophers[i].start();
} ...
while (true) {
try {
// sleep 1 séc
Thread.steep(1000);
// check for deadlock
boolean deadlock = true;
for (Fork f : forks) {
if (f.isFree()) {
deadlock = talse;
break;
}'
}
if (deadlock) {
Thread.steep(1000);
System.out.println("cảnh báo! Đã đẽn giới hạn Deadlock!");
break;
}
}
catch (Exception e) {
e.printStackTrace(System.out);
}
}
System.out.println("Bye!");
System.exit(0);
}

- Phương thức Main, là phương thức sẽ sử dụng hai class mà đã tạo là class Fork và

class Philosopher để chạy chương trình.
|for (int i = 0; i < phiLosophersNìỉber; i++) {
/orks[i] = new Fork()j
}

- Dùng để tạo một mảng chứa các đối tượng đũa.
|for (int i = 0; ỉ < phiLosophersNumber; i++) {
phitosophers[i] = new Philosopher(i, yorfes[i]j forks[(i + 1) % phiLosophersNumber]);
phiLosophers[i].start();
}---

- Dùng để tạo mảng gán các đối tượng nhà triết gia và khởi động luồng.


uhile (true) {
try {
/Ị sleep 1 sec
Thread.sLeep(1000);
Ị ị check for deadlock
bũũlean deadlock = truej
for (Fork f : /ơrks) {
if (í.isFree()) {
deadlũck = fal.se;
break;
}
}
if (deadlock) {
Thread.steep(1000);
System.out.printỉn("Cảnh báo! Đã đến giới hạn Deadlock!")j
break;

}
}
catch (Exception e) {
e.prĩntStackTrace(System.out);
}
}
System.out.println("Bye!");
System.exit(0);
}

- Với vòng lặp While, vòng lặp này sẽ có tác dụng kiểm tra q trình Deadlock. Tất
cả các luồng được kiểm tra về tài nguyên đang được chiếm giữ. Nếu như tất cả các
luồng bị quá tải do không đủ tài nguyên, dẫn đến giới hạn của Deadlock, người
dùng
sẽ nhận một cảnh báo và tự động dừng chương trình.


KẾT LUẬN
Qua bài tập này, chúng ta sẽ hiểu rõ hơn về cách thức hoạt động của luồng
trong hệ điều hành, cách các luồng nhận và giả lại tài nguyên sao cho hợp lý để cho
hệ điều hành hoạt động tốt nhất có thể. Và hiểu thêm về thuật tốn Semaphore và
cách thức hoạt động của nó, kết hợp với luồng, để có thể sử dụng trong một trường
hợp nào đấy trong tương lai. Em cảm ơn thầy đã cho em cơ hội được nghiên cứu về
đề tài này và giúp em có thêm kiến thức. Em xin cảm ơn!



×