Thực hành Hệ điều hành - Bài thực hành số 6.1: Semaphore

Tài nguyên dùng chung là tài nguyên mà nhiều process ₫ồng thời (hay thread) có
thể truy xuất ₫ược. Nếu ₫ể các process truy xuất ₫ồng thời tự do tài nguyên thì dễ làm
hư hỏng tài nguyên, do ₫ó cần phải có cơ chế kiểm soát việc truy xuất ₫ồng thời này.
Hiện nay ta dùng cơ chế loại trừ tương hỗ giữa các process ₫ồng thời, nghĩa là tối
₫a 1 process ₫ược phép truy xuất tài nguyên tài từng thời ₫iểm.
Ta gọi "critical section" - CS là ₫oạn code của process mà truy xuất tài nguyên
dùng chung, do ₫ó nó cần ₫ược chạy theo tính nguyên tử (không thể chia cắt, không
thể thấy từ ngoài, không thể dừng ₫ột ngột,...) 
pdf 5 trang xuanthi 30/12/2022 860
Bạn đang xem tài liệu "Thực hành Hệ điều hành - Bài thực hành số 6.1: Semaphore", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.

File đính kèm:

  • pdfthuc_hanh_he_dieu_hanh_bai_thuc_hanh_so_6_1_semaphore.pdf

Nội dung text: Thực hành Hệ điều hành - Bài thực hành số 6.1: Semaphore

  1. Trang 2 • SEM cs = new SEM(cnt) : tạo 1 semaphore với counter ban ₫ầu là cnt. • cs.down() : yêu cầu truy xuất tài nguyên tương ứng. Nếu không còn tài nguyên thì process này sẽ bị giam vào hàng ₫ợi (Blocked). • cs.up() : giải phóng tài nguyên ₫ang dùng, nếu hàng ₫ợi không trống, chọn 1 process và cho nó chạy tiếp. • delete(cs) : xóa semaphore, nếu hàng ₫ợi của nó không trống thì cần xử lý lỗi. 2. Hãy hiện thực 2 tác vụ down() và up() bằng cách dùng các tác vụ sau : • TASK current : miêu tả process hiện hành (Running). • void insert(TASK t, List lstBlocked) : thêm process vào hàng ₫ợi • cs.up() : giải phóng tài nguyên ₫ang dùng, nếu hàng ₫ợi không trống, chọn 1 process và cho nó chạy tiếp. • TASK remove(List lstBlocked) : lấy 1 process trong hàng ₫ợi ra (và xóa nó trong hàng ₫ợi). class SEM { int cnt; List lstBlocked = new List (); public SEM(int cnt) { this.cnt = cnt; } //tác vụ down public void down() { cnt ; //a if (cnt < 0) { //b current.state = BLOCKED; //c insert(current,cs.lstBlocked);//d commut(); //chuyển ngữ cảnh cho thành phần khác chạy } } //tác vụ up public void up() { TASK t; cnt++; //x if (cnt <= 0) { //y t = Remove(lstBlocked); //z t.state = READY; //t } } } 3. Hãy giải thích tại sao các tác vụ down và up phải có tính nguyên tử trong khi thực thi và ta hiện thực tính nguyên tử này như thế nào ? Giả sử giá trị ban ₫ầu của cnt là 1. Nếu 2 process thi hành chuỗi lệnh a1 a2 b2 b1, cả 2 process ₫ều bị blocked nhưng biến cnt vẫn là -1, do ₫ó sau này, 1 trong 2 process sẽ không bao giờ ₫ược giải phóng. Tệ hơn nửa, nếu process lệnh up cũng là process lệnh down trước ₫ó, thì sẽ có deadlock vì không ai thực thi tác vụ V nữa cả.
  2. Trang 4 int a = 6; SEM m1 = new SEM(1); SEM m2 = new SEM(0); Process A Process B Process C m1.down(); a = a - 5; m1.up(); a = a + 7; m2.down(); m2.up(); a = a * 3; 7. Biến a có thể nhận những giá trị nào sau khi chạy 3 process ? Ứng với mỗi giá trị có thể của a, hãy miêu tả trình tự thi hành các lệnh tạo ra kết quả tương ứng. ABC -> 24 ACB -> 34 BAC -> 24 Lưu ý semaphore m1 hoàn toàn không có tác dụng gì trong trường hợp chạy trên. 8. • Hãy thêm các semaphore cần thiết vào các ₫oạn lệnh của 3 process trên ₫ể sau khi chạy xong 3 process, biến a luôn = 34. Miêu tả phần thiết lập giá trị ₫ầu cho các semaphore ₫ược thêm mới. • cùng câu hỏi trên ₫ể giá trị a = 24. Chỉ 1 kịch bản chạy sau có thể tạo ra a = 34 : ta tạo thêm semaphore m3 với giá trị ₫ầu = 0 ₫ể kiểm soát B ₫ược chạy chỉ sau C hoàn thành : Process A Process B Process C m1.down(); m3.down(); m1.up(); a = a + 7; a = a - 5; m2.down(); m2.up(); a = a * 3; m3.up(); Có 2 kịch bản chạy sau có thể tạo ra a = 24 : ta tạo thêm semaphore m3 với giá trị ₫ầu = 0 ₫ể kiểm soát C chạy sau cùng : Process A Process B Process C m1.down(); a = a - 5; m1.up(); a = a + 7; m3.up(); m2.down(); m2.up(); m3.down(); a = a * 3; 9. Semaphore nào có thể ₫ược loại bỏ mà không cần hiệu chỉnh việc thi hành các process ? Giải thích. Semaphore m1 không bao giờ kẹt. Do ₫ó nó không cần thiết. 10. Ta hiệu chỉnh sự ₫ồng bộ hóa giữa các process như sau : Process A Process B Process C m1.down(); m2.down(); m2.down(); m2.down(); a = a - 5; m1.down(); a = a + 7; m2.up(); a = a * 3; m1.up(); m1.up(); m2.up(); m2.up();