Chúng ta có tình huống bế tắc xảy ra, bởi vì tiến trình A đã có máy in và tiến trình B đã có bộ nhớ và không một tiến trình nào có thể tiếp tục vì tài nguyên đã bị chiếm giữ bởi tiến trì
Trang 1ĐẠI HỌC ĐÀ NẴNG
-
-BÀI TIỂU LUẬN
HỆ PHÂN TÁN
Giảng viên: PGS TS Lê Văn Sơn Học viên : Võ Đức Hoàng
Lớp: Khoa học máy tính K11
Trang 3LỜI MỞ ĐẦU
Hệ tin học phân tán là hệ thống rất đa dạng, đa diện, phức tạp về mặt cấu trúc, là vùng tri thức hiện đại đang được các chuyên gia công nghệ thông tin đặc biệt quan tâm và đổi mới rất nhanh chóng
Một trong những tư tưởng lớn của các hệ phân tán là phân tán hóa các quá trình xử lý thông tin và thực hiện các công việc đó trên các trạm xa nhau.
Đó là cơ sở để xây dựng các hệ ứng dụng lớn như thương mại điện tử, giáo dục điện tử, chính phủ điện tử .
Trong quá trình phát triển hệ phân tán, một vấn đề rất được quan tâm là phát hiện và xử lý bế tắc Vấn đề này thu hút nhiều sự quan tâm của các nhà nghiên cứu nhằm tìm ra các giải pháp hữu hiệu đảm bảo hệ thống hoạt động
ổn định.
Trong nội dung tiểu luận này trình bày các vấn đề về bế tắc, cách phát hiện và ngăn chặn bế tắc xảy ra trong hệ thống, tiểu luận gồm hai phần:
Phần 1: Lý thuyết.
Trình bày các khái quát về bế tắc Các thuật toán phát hiện và ngăn chặn bế tắc.
Phần 2: Bài tập.
Trình bày giải pháp kết hợp các bộ tuần tự cho mỗi tài nguyên găng trên một jeton tuần hoàn để ngăn chặn bế tắc.
liệu để em thực hiện tiểu luận này.
Rất mong nhận được sự góp ý của thầy và các bạn.
Trang 4Phần 1: LÝ THUYẾT
Trong các hệ thống máy tính có nhiều tài nguyên mà chỉ được sử dụng bởi một tiến trình tại mỗi thời điểm Ví dụ như máy vẽ, đầu đọc CD-ROM, đầu ghi CD-ROM, và các slot trong bảng tiến trình của hệ thống Có hai tiến trình cùng đồng thời ghi vào máy in Hai tiến trình đó cùng sử dụng một slot trong bảng tiến trình Vì vậy, tất cả các hệ điều hành đều có thể cho phép một tiến trình truy xuất độc quyền đến các tài nguyên
Trong nhiều ứng dụng, một tiến trình cần phải độc quyền truy cập không chỉ đến một
mà đến nhiều tài nguyên khác
Bế tắc có thể xảy ra trong nhiều tình huống yêu cầu truy cập đến các thiết bị Vào/Ra
Ví dụ, trong hệ cơ sở dữ liệu, một chương trình có thể bị khoá vài bản ghi mà nó đang dùng, để tránh điều kiện tranh chấp Nếu tiến trình A khoá bản ghi R1 và tiến trình B khoá bản ghi R2 và sau đó mỗi tiến trình thử khoá bản ghi của tiến trình khác, thì cũng sẽ
bế tắc Vì vậy, bế tắc có thể xảy ra trên các tài nguyên phần cứng cũng như các tài nguyên phần mềm
I Các tài nguyên
Bế tắc có thể xảy ra khi các tiến trình truy xuất độc quyền đến các thiết bị, file, v.v
Để thảo luận bế tắc, chúng ta sẽ tham chiếu đến các đối tượng như tài nguyên Một tài nguyên có thể là một thiết bị phần cứng hay một phần của thông tin Một máy tính có thể
có nhiều tài nguyên khác nhau có thể được yêu cầu
Tài nguyên có thể phân thành hai loại: có thể thu hồi (preemptable) và không thể thu hồi (nonpreemptable)
Tài nguyên có thể thu hồi: là tài nguyên có thể được lấy ra từ tiến trình sở hữu nó.
Bộ nhớ là một ví dụ của tài nguyên có thể thu hồi
Ví dụ: một hệ thống với 512 KB bộ nhớ sử dụng, một máy in và hai tiến trình 512 KB
mà mỗi tiến trình đều muốn in cái gì đó Tiến trình A yêu cầu và chiếm hữu máy in, sau
đó thực hiện tính toán các giá trị để in Trước khi tiến trình A hoàn thành tính toán, thì đã vượt quá thời gian quantum dành cho nó và bị chuyển trở ra khỏi bộ nhớ
Bây giờ tiến trình B chạy thực hiện để yêu cầu máy in nhưng không thành công Chúng ta có tình huống bế tắc xảy ra, bởi vì tiến trình A đã có máy in và tiến trình B đã
có bộ nhớ và không một tiến trình nào có thể tiếp tục vì tài nguyên đã bị chiếm giữ bởi tiến trình khác Cuối cùng, có thể thu hồi bộ nhớ từ tiến trình B bằng cách chuyển tiến trình B ra và chuyển tiến trình A vào Bây giờ tiến trình A có thể chạy thực hiện in và sau
đó giải phóng máy in Bế tắc không xảy ra
Tài nguyên không thể thu hồi được: là tài nguyên mà không thể lấy ra từ
tiến trình hiện đang sở hữu nó bất kể gây ra lỗi tính toán File, các thiết bị Vào /Ra là các tài nguyên không thể thu hồi được
Nhìn chung, các bế tắc thường xảy ra đối với các tài nguyên không thể thu hồi được
Trang 5Trình tự của các sự kiện yêu cầu sử dụng tài nguyên là:
- Yêu cầu một tài nguyên
- Sử dụng tài nguyên
- Giải phóng tài nguyên
Nếu tài nguyên không có giá trị khi được yêu cầu thì tiến trình yêu cầu bị chặn để chờ Trong một số hệ điều hành, tiến trình tự động bị chặn khi tài nguyên yêu cầu bị lỗi
và đánh thức dậy khi tài nguyên có giá trị
II Định nghĩa bế tắc:
Một tập các tiến trình bị bế tắc nếu mỗi tiến trình trong tập tiến trình chờ một sự kiện
mà chỉ có tiến trình khác trong tập các tiến trình đó tạo ra.
Tất cả các tiến trình đều đang chờ, không một tiến trình nào trong chúng có thể tạo ra bất kỳ một sự kiện nào để có thể đánh thức tiến trình khác trong tập tiến trình, vì vậy tất
cả các tiến trình tiếp tục chờ mãi mãi
Trong hầu hết các trường hợp, sự kiện mà tiến trình đang chờ giải phóng vài tài nguyên hiện mà tiến trình khác trong tập tiến trình bị chặn đang chiếm giữ Hay nói cách khác, mỗi thành viên của tập các tiến trình bế tắc đang chờ tài nguyên là sở hữu của một tiến trình bị chặn khác Không một tiến trình nào có thể chạy thực hiện, không một tiến trình nào có thể giải phóng tài nguyên và cũng không một tiến trình nào có thể thức dậy
III Điều kiện xảy ra bế tắc
Cofman, Elphick và Shosani vào năm 1971 đã đưa ra 4 điều kiện cần có thể làm xuất hiện bế tắc:
1 Có sử dụng tài nguyên không thể chia sẻ (Mutual exclusion):
Mỗi thời điểm, một tài nguyên không thể chia sẻ được hệ thống cấp phát chỉ một tiến trình, khi tiến trình sử dụng xong tài nguyên này hệ thống mới thu hồi và cấp phát tài nguyên cho hệ thống khác
2 Sự chiếm giữ và yêu cầu thêm tài nguyên (Wait for):
Tiến trình được phép giữ và yêu cầu thêm một hoặc nhiều tài nguyên và chờ cung cấp tài nguyên đang bị tiến trình khác chiếm giữ
3 Không thu hồi được tài nguyên từ tiến trình đang giữ chúng (No preemption):
Tài nguyên chỉ tự nguyện giải phóng khi sử dụng xong Không một tiến trình nào hay
hệ điều hành có thể thu hồi tài nguyên từ tiến trình đang chiếm giữ chúng
4 Tồn tại một chu kỳ chờ trong đồ thị cấp phát tài nguyên (Circular wait)
Có ít nhất hai tiến trình chờ đợi lẫn nhau: tiến trình này chờ cấp phát tài nguyên đang
bị tiến trình kia chiếm giữ và ngược lại
Tất cả 4 điều kiện này cần phải ngăn chặn để bế tắc không xảy ra Khi có đủ 4 điều kiện này thì bế tắc xảy ra Nếu thiếu 1 trong 4 điều kiện này thì không có bế tắc
Trang 6IV Đồ thị cấp phát tài nguyên
Có thể sử dụng một đồ thị để mô hình hóa viêc cấp phát tài nguyên Đồ thị này được gọi là đồ thị định vị tài nguyên (RSG : Resource Allcation Graph):
- 2 loại nút: các tiến trình được biểu diễn bằng hình tròn, và mỗi tài nguyên được hiển thị bằng hình vuông
- 2 loại cạnh:
+ Cạnh yêu cầu: từ tiến trình đến tài nguyên Chỉ rõ tiến trình yêu cầu tài nguyên
và chờ có được tài nguyên đó
+ Cạnh chỉ định: từ tài nguyên đến tiến trình Chỉ rõ tiến trình đang chiếm giữ tài nguyên đó
Khi một yêu cầu được thực hiện, một cạnh yêu cầu được thêm vào
Khi một yêu cầu được hoàn thành cạnh yêu cầu được chuyển sang cạnh chỉ định Khi một tiến trình giải phóng tài nguyên, cạnh chỉ định bị xóa đi
Nếu đồ thị không chứa chu kỳ thì bế tắc không xảy ra
Nếu đồ thị chứa một chu kỳ thì bế tắc xảy ra
Hình 1.1 Đồ thị cấp phát tài nguyên.
V Các phương pháp xử lý bế tắc
Chủ yếu có 3 phương hướng tiếp cận để xử lý bế tắc:
P P đang giữ R
R
P P yêu cầu R
R
R3 P1
R2 P2 P3 Một tình huống không bế tắc
R1
R4
R3 P1
R2 P2 P3 Một tình huống bế tắc
R1
R4
Trang 7- Sử dụng một giao thức (protocol) để hệ thống không bao giờ xảy ra bế tắc.
- Cho phép xảy ra bế tắc và tìm cách sửa chữa bế tắc
- Hoàn toàn bỏ qua bế tắc, xem như hệ thống không bao giờ xảy ra bế tắc
VI Ngăn chặn bế tắc
Để bế tắc không xảy ra cần đảm bảo tối thiểu một trong 4 điều kiện cần không xảy ra như sau:
1 Tài nguyên không thể chia sẻ: gần như không thể tránh được điều kiện này vì bản
chất tài nguyên gần như cố định Tuy nhiên đối với một tài nguyên về kết xuất, người ta
có thể dùng các cơ chế spooling để biến đổi thành tài nguyên có thể chia sẻ
2 Sự chiếm giữ và yêu cầu thêm tài nguyên: phải đảm bải rằng mỗi khi tiến trình
yêu cầu thêm một tài nguyên thì nó không chiếm giữ các tài nguyên khác Có thể áp đặt một trong hai cơ chế truy xuất sau:
- Tiến trình phải yêu cầu tất cả các tài nguyên cần thiết trước khi bắt đầu xử lý: phương pháp này có khó khăn là tiến trình khó có thể ước lượng chính xác tài nguyên cần
sử dụng vì có thể nhu cầu phụ thuộc vào quá trình xử lý Ngoài ra nếu tiến trình chiếm giữ sẵn các tài nguyên chưa cần sử dụng ngay thì việc sử dụng tài nguyên sẽ kém hiệu quả
- Khi tiến trình yêu cầu một tài nguyên mới và bị từ chối nó phải giải phóng các tài nguyên đang chiếm giữ, sau đó lại được cấp phát trở lại cùng lần với tài nguyên mới: phương pháp này làm phát sinh các khó khăn trong việc bảo vệ tính toàn vẹn dữ liệu của
hệ thống
3 Thu hồi tài nguyên: Cho phép hệ thống được thu hồi tài nguyên từ các tiến trình bị
khóa và cấp phát trở lại cho tiến trình khi nó thoát khỏi tình trạng bị khóa Tuy nhiên với một số loại tài nguyên, việc thu hồi sẽ rất khó khăn vì vi phạm tính toàn vẹn dữ liệu
4 Tồn tại một chu kỳ: tránh tạo chu kỳ trong đồ thị cấp phát bằng cách cấp phát tài
nguyên theo thứ tự phân cấp như sau:
Gọi R = { R1, R2, , Rn } là tập các loại tài nguyên
Các loại tài nguyên được phân thứ tự từ 1 – N, thứ tự có thể là thứ tự logic mà tài nguyên thường yêu cầu Ký hiệu F(Ri)
Các tiến trình khi yêu cầu tài nguyên phải tuẩn thủ quy định: khi tiến trình đang bị chiếm giữ tài nguyên Ri thì có thể yêu cầu các tài nguyên Rj nếu F(Rj) > F(Ri)
VII Thuật toán phát hiện bế tắc
Khi các tài nguyên được sử dụng bởi giao dịch được xác định theo kiểu động trong quá trình thi hành giao dịch, các phương pháp dự phòng bế tắc dựa trên nền tảng các thông điệp không còn phù hợp nữa Lúc này, ta phải sử dụng các phương pháp phát hiện
và chữa trị
Trang 8Phương pháp được mô tả bởi Menasce sẽ được trình bày Phương pháp này đặt ra vấn đề sử dụng một đồ thị các tranh chấp mà việc kiểm tra các tranh chấp đó cho phép phát hiện bế tắc
Tương tự như thuật toán vừa nêu, mỗi một trạm quản lý các đối tượng riêng của mình và việc phát hiện chỉ dựa vào thông tin cục bộ Các trạm khởi sự các giao dịch bị treo được đề phòng phát sinh bế tắc (mà bế tắc này có thể phát hiện tại một trạm nào đó) cần phải đề ra các biện pháp chữa trị cho mình
1 Các định nghĩa
Ta cần xác định trong mọi thời điểm giữa hai giao dịch T j và T k quan hệ chặn
trực tiếp như sau:
Quan hệ này được biểu hiện bằng một đồ thị gọi là đồ thị các xung đột hữu hiệu
Sự tồn tại một vòng lặp trong đồ thị này báo hiệu cho ta biết sẽ có bế tắc diễn ra Một giao dịch “không bị chặn” có nghĩa là trong đồ thị biểu hiện bằng một nút mà tại đó không có cung nào dẫn đến
Giả sử rằng T k là một giao dịch bị chặn tập hợp tất cả các giao dịch mà có thể
đạt được bằng cách chạy khắp các cung xuất phát từ T k, theo chiều ngược lại với
hướng của chúng, và gọi là tập hợp các chặn của T k , ký hiệu là E(T k ) Các giao dịch
thuộc vào E(T k ) là các giao dịch có nguồn gốc từ sự chặn của T k
Tại một thời điểm cho trước, đồ thị các xung đột hữu hiệu sinh ra các quan hệ
chặn tồn tại giữa các giao dịch của hệ Ta ký hiệu B(T k ) là tập hợp các giao dịch bị
chặn do T k, có nghĩa là các giao dịch có thể đạt được bằng cách chạy khắp các xuất
phát từ T k
Ví dụ : Cho đồ thị các xung đột hữu hiệu như sau:
Các giao dịch không chặn là T 3 , T 4 , T 5
Ta có:
E(T1) = { T2, T3, T4 T5 } B(T5) = { T1, T2 }
T j > T k Tồn tại ít nhất một tài nguyên bị cài then bởi T j và
yêu cầu bởi T k nhưng không được đáp ứng
T1
T2
T5
T3 T4
Trang 9Đồ thị các xung đột hữu hiệu chứa vòng lặp nếu và chỉ nếu tồn tại giao dịch T k
k: B(Tk) E(Tk) {Tồn tại vòng lặp}
Nếu ta không muốn duy trì trên mỗi trạm một bản sao của đồ thị tổng quát thì cần phải xây dựng một ảnh cục bộ cho phép đánh giá các điều kiện vừa nêu trên Đó
là điều mà ta thực hiện trong giải thuật sau đây
2 Thuật toán
Ta ký hiệu S(T k ) là trạm nguồn của giao dịch T k để cho mỗi giao dịch T k, trạm S(Tk) duy trì các tập hợp B(T k ) và E(T k ) Việc cập nhật E(T k ) cần phải được biểu hiện
trên tất cả các trạm nguồn của các giao dịch thuộc B(T k ) Thực tế, giao dịch chặn T k là
phần tử của toàn bộ tập hợp chặn cảu các giao dịch thuộc B(T k ).
Giả sử rằng T k đã yêu cầu một tài nguyên e của trạm S i nào đó Trên trạm này, ta thực hiện các phép toán sau đây:
STT Phép toán
1 Nếu e là có sẵn để dùng, yêu cầu được thoả mãn và ta ghi nhận là T k
đang có tài nguyên
2
Nếu e đã được cung cấp cho giao dịch T j thì thông điệp “Tj chặn Tk”
được truyền cho trạm S(T j ) và S(T k ) Sau này (j,k) chỉ một thông điệp
như vậy
Khi nhận một thông điệp (j,k) trên một trạm S nào đó, ta thực hiện các tác động
sau đây:
1 Trên trạm S(T j ) nguồn của giao dịch chặn Tk, ta thêm T k vào tập hợp B(T j ) và
kiểm tra rằng ta không làm phát sinh bế tắc, có nghĩa là:
B(Tj) E(Tj) =
Ta gửi tiếp tục thông điệp (l,k) về phía các trạm nguồn của các giao dịch T l chặn
T j nhằm cho phép các trạm S(T l ) cập nhật các tập hợp B(T l ) của các giao dịch bị chặn
bởi T l Song song với tác động trên, các thông điệp (l,k) được gửi về trạm nguồn của
các giao dịch T k để cập nhật tập hợp E(T k ) của các giao dịch chặn T k
2 Trên trạm S(T k ) nguồn của giao dịch bị chặn T k , ta thêm T j cho tập hợp E(T k )
và kiểm tra không có bế tắc, có nghĩa là:
B(TJ) E(Tk) =
Ta gửi tiếp tục thông điệp (j,m) về phía các trạm nguồn của các giao dịch T m bị
chặn bởi T k nhằm cho phép các trạm S(T m ) cập nhật các tập hợp E(T m ) của các giao
dịch chặn T m
Các khuyến nghị giải phóng dẫn đến thuật toán đối xứng mà ta không có điều kiện giới thiệu ở đây
Trang 10Ví dụ 2: Hãy xét 3 trạm S1, S2 và S3 Mỗi trạm S i chứa đối tượng e i và là nguồn
của giao dịch T i:
v_loai_tru_th(e1)
v_loai_tru_th(e2)
v_loai_tru_th(e2)
v_loai_tru_th(e3)
v_loai_tru_th(e3)
v_loai_tru_th(e1)
Ta hãy tưởng tượng rằng tại thời điểm mà tất cả các giao dịch đã được thực hiện
có kết quả phép toán đầu tiên của then cài Khi đó chuyển sang thời điểm của phép toán thứ hai, các giao dịch đều bị chặn Điều đó kéo theo các sự kiện sau đây:
T 1 trên S2 đề nghị cung cấp e2 có trên T2;
S2 gửi (2,1) cho S1 và S2, từ đó ta có:
E(T1) = {T2} B(T1) = B(T2) = {T1} E(T2) =
T 2 trên S3 đề nghị cung cấp e3 có trên T3;
S3 gửi (3,2) cho S2 và S3, từ đó ta có :
B(T3) = {T2} E(T3) = E(T2) = {T3} B(T2) = {T1}
S2 gửi (3,1) cho S1 và từ đó sinh ra:
E(T1) = {T2, T3} B(T1) =
T 3 trên S3 đề nghị cung cấp e1 có trên T1;
S1 sinh ra T3 trong B(T1) và ta ghi nhận là:
E(T1) B(T1) = {T3} Như vậy, bế tắc được phát hiện trên S1
VIII Kết luận
Hai thuật toán vừa được giới thiệu ở trên xuất phát từ cơ sở cùng một nguyên lý tương tự Đó là sự thiếu chắc chắn trạng thái các trạm xa phát sinh vấn đề lưu trữ một
"giới hạn an toàn" nhất định Điều đó lại ngăn cản các phép toán không kéo theo bế tắc
Nhưng bản thân hai thuật toán này, khi triển khai lại cho phép sử dụng các kỹ thuật khác nhau Trong thuật toán dự phòng ta kiểm tra trên trạng thái từng phần một điều kiện mạnh hơn điều kiện tối thiểu Trong thuật toán phát hiện ta có trong một trạm trạng thái của các trạm khác Thông thường, mỗi trạm đều nhận các thông tin dư thừa