Bài giảng Lập trình đồng thời và phân tán - Bài 6: Bài toán truy cập tài nguyên chỉa sẻ cung cấp cho người học các kiến thức: Bài toán loại trừ lẫn nhau trong hệ thống phân tán, những thuật toán dựa trên timestamp, những thuật toán dựa trên token. Mời các bạn cùng tham khảo.
LẬP TRÌNH ĐỒNG THỜI & PHÂN TÁN BÀI 6: BÀI TOÁN TRUY CẬP TÀI NGUYÊN CHỈA SẺ Giảng viên: Lê Nguyễn Tuấn Thành Email: thanhlnt@tlu.edu.vn NỘI DUNG ▪Bài toán loại trừ lẫn hệ thống phân tán ▪Những thuật toán dựa timestamp ▪Những thuật toán dựa token Bài giảng có sử dụng hình vẽ sách “Concurrent and Distributed Computing in Java, Vijay K Garg, University of Texas, John Wiley & Sons, 2005” Bài toán loại trừ lẫn hệ thống phân tán ▪ Xét hệ thống phân tán bao gồm số lượng cố định tiến trình tài nguyên chia sẻ ▪ Việc truy cập đến tài nguyên chia sẻ coi khu vực quan trọng CS ▪ Yêu cầu: Đưa thuật toán để phối hợp truy cập tới tài nguyên chia sẻ thỏa mãn thuộc tính sau: Safety: hai tiến trình khơng có quyền truy cập đồng thời vào CS Liveness: yêu cầu tới CS cuối phải cấp quyền Fairness: yêu cầu khác phải cấp quyền vào CS theo thứ tự mà chúng tạo ▪ Giả sử khơng có lỗi hệ thống phân tán, xử lý liên kết giao tiếp tin cậy Giao diện Xử lý thơng điệp Khố Những thuật tốn dựa timestamp Thuật toán mutex Lamport (1) ▪ Trong thuật tốn này, tiến trình lưu giữ: Một đồng hồ vector V (dùng để lưu dấu thời gian) Một hàng đợi Q (dùng để lưu yêu cầu vào CS tiến trình hệ thống phân tán) ▪ Thuật toán đảm bảo: tiến trình vào CS theo thứ tự dấu thời gian u cầu phía tiến trình gửi ▪ Chứ thứ tự nhận u cầu bên phía tiến trình nhận ! ▪ Giả sử thông điệp truyền theo thứ tự FIFO Thuật toán mutex Lamport (2) ▪ Nếu hai u cầu có dấu thời gian, u cầu tiến trình có số hiệu nhỏ coi nhỏ ▪ Một cách thức, Pi vào CS nếu: ▪ q[i], q[j]: dấu thời gian yêu cầu vào CS hai tiến trình Pi Pj ▪ v[j]: dấu thời gian thơng điệp xác nhận từ tiến tình Pj ghi nhận tiến trình Pi Các bước thực (1) Khi tiến trình Pi muốn vào CS ▪ Pi gửi thơng điệp request có gắn dấu thời gian tới tất tiến trình khác ▪ Đồng thời, Pi thêm yêu cầu có gắn dấu thời gian vào hàng đợi Khi tiến trình Pk nhận thơng điệp request từ tiến trình Pi ▪ Pk lưu yêu cầu dấu thời gian yêu cầu hàng đợi ▪ Pk gửi ngược lại thông điệp ack (xác nhận) có gắn dấu thời gian cho Pi Các bước thực (2) Một tiến trình Pj nhận thấy vào CS thoả mãn điều kiện sau: ✔ Pj có yêu cầu hàng đợi với dấu thời gian t nhỏ tất yêu cầu khác hàng đợi ✔ Pj nhận thơng điệp ack (xác nhận) từ tất tiến trình khác với dấu thời gian lớn t Để giải phóng CS, tiến trình Pj gửi thơng điệp release tới tất tiến trình khác ▪ Khi tiến trình Pm nhận thơng điệp release, Pm xố yêu cầu tương ứng Pj khỏi hàng đợi public class LamportMutex extends Process implements Lock { public synchronized void requestCS() { v.tick(); q[myId] = v.getValue(myId); broadcastMsg("request", q[myId]); while (!okayCS()) myWait(); } public synchronized void releaseCS() { q[myId] = Symbols.Infinity; broadcastMsg("release", v.getValue(myId)); } boolean okayCS() { for (int j = 0; j < N; j++){ //REQ// if(isGreater(q[myId], myId, q[j], j)) return false; //ACK// if(isGreater(q[myId], myId, v.getValue(j), j))return false; } return true; } public synchronized void handleMsg(Msg m, int src, String tag) { int timeStamp = m.getMessageInt(); v.receiveAction(src, timeStamp); if (tag.equals("request")) { q[src] = timeStamp; sendMsg(src, "ack", v.getValue(myId)); } else if (tag.equals("release")) q[src] = Symbols.Infinity; else if (tag.equals(”ack")) v[src] = timeStamp; notify(); // okayCS() may be true now 10 } Đánh giá thuật toán mutex Lamport Sử dụng 3*(N-1) thông điệp cho lần yêu cầu CS ▪ ▪ ▪ N - thông điệp request N - thông điệp ack (xác nhận) N - thơng điệp release 11 Thuật tốn Ricart Agrawala ▪ Sử dụng đồng hồ logic C hàng đợi pendingQ ▪ Kết hợp chức thông điệp ack (xác nhận) thông điệp release thành thơng điệp okay ▪ Trong thuật tốn này, tiến trình Pk lúc gửi thông điệp okay ngược lại nhận thông điệp request từ tiến trình Pi ▪ Nó trì hỗn xác nhận sau khoảng thời gian ▪ Thuật toán sử dụng 2*(N-1) thông điệp cho lần yêu cầu CS ▪ Thay 3*(N-1) thơng điệp thuật tốn Lamport 12 Các bước thực (1) Khi tiến trình Pi muốn yêu cầu CS (để sử dụng tài nguyên chia sẻ) ▪ Pi gửi thông điệp request gắn dấu thời gian tới tất tiến trình khác Khi tiến trình Pk nhận thơng điệp request từ tiến trình gửi Pi ▪ Pk gửi thông điệp okay nếu: ▪ Pk không quan tâm đến việc vào CS, ▪ Yêu cầu CS Pk có dấu thời gian lớn so với Pi ▪ Nếu khơng, u cầu tiến trình gửi Pi lưu hàng đợi Pk 13 Các bước thực (2) Một tiến trình Pj vào CS khi: ✔ Pj yêu cầu tài nguyên chia sẻ cách gửi thông điệp request tới tất tiến trình khác, ✔ Pj nhận N-1 thơng điệp okay từ N-1 tiến trình khác xác nhận cho thơng điệp request Khi tiến trình Pj giải phóng tài ngun ▪ Pj gửi thơng điệp okay cho tiến trình hàng đợi Pj 14 public class RAMutex extends Process implements Lock { public synchronized void requestCS() { c.tick(); myts = c.getValue(); broadcastMsg("request", myts); numOkay = 0; while (numOkay < N-1) myWait(); } public synchronized void releaseCS() { myts = Symbols.Infinity; while (!pendingQ.isEmpty()) { int pid = pendingQ.removeHead(); sendMsg(pid, "okay", c.getValue()); } } public synchronized void handleMsg(Msg m, int src, String tag) { int timeStamp = m.getMessageInt(); c.receiveAction(src, timeStamp); if (tag.equals("request")) { if ((myts == Symbols.Infinity ) || (timeStamp < myts) ||((timeStamp == myts)&&(src < myId)))//not interested in CS sendMsg(src, "okay", c.getValue()); else pendingQ.add(src); } else if (tag.equals("okay")) { numOkay++; if (numOkay == N - 1) notify(); // okayCS() may be true now 15 } } } 16 Những thuật toán dựa token Thuật toán dựa Token ▪Sử dụng tài nguyên phụ, token, cho hệ thống phân tán với tài nguyên chia sẻ ▪Nhiệm vụ: tạo, lưu giữ luân chuyển yêu cầu token tiến trình hệ thống phân tán 17 Thuật toán mutex tập trung ▪ Thuật tốn tốn cho toán loại trừ lẫn nhau, dựa hàng đợi ▪ Thuật tốn thoả mãn hai thuộc tính safety liveness ! ▪ Một số tiến trình đóng vai trị Người lãnh đạo (Leader), Người điều phối (Coordinator) cho việc vào CS ▪ Biến haveToken có giá trị True cho tiến trình có quyền truy cập tới CS ▪ Lúc đầu có haveToken Leader True ▪ haveToken tất tiến trình khác False ▪ Trong thời điểm, có tiến trình có giá trị haveToken True 18 Các bước thực Khi tiến trình Pi muốn vào CS, gửi thơng điệp request đến tiến trình Leader Khi nhận thơng điệp request, tiến trình Leader đặt request vào hàng đợi pendingQ Leader cấp quyền cho tiến trình Pk đầu hàng đợi cách gửi thông điệp okay cho Pk Khi tiến trình Pk hồn thành cơng việc CS nó, Pk gửi thơng điệp release tới Leader Khi nhận thông điệp release, Leader gửi thông điệp okay tới tiến trình hàng đợi pendingQ, hàng đợi không rỗng ▪ Nếu không, Leader đặt giá trị haveToken thành True 19 public class CentMutex extends Process implements Lock { public synchronized void requestCS() { sendMsg(leader, "request"); while (!haveToken) myWait(); } public synchronized void releaseCS() { sendMsg(leader, "release"); haveToken = false; } public synchronized void handleMsg(Msg m, int src, String tag) { if (tag.equals("request")) { if (haveToken){ sendMsg(src, "okay"); haveToken = false; } else pendingQ.add(src); } else if (tag.equals("release")) { if (!pendingQ.isEmpty()) { int pid = pendingQ.removeHead(); sendMsg(pid, "okay"); } else haveToken = true; } else if (tag.equals("okay")) { haveToken = true; notify(); } } 20 Đánh giá thuật toán mutex tập trung ▪ Thuật tốn mutex tập trung khơng thoả mãn thuộc tính cơng bằng! ▪ Các yêu cầu NÊN cấp quyền vào CS theo thứ tự mà chúng tạo theo thứ tự mà chúng nhận ▪ Giả sử tiến trình Pi gửi yêu cầu vào CS cho tiến trình Leader ▪ Sau tiến trình Pj gửi yêu cầu vào CS tới Leader yêu cầu Pj đến tiến trình Leader sớm yêu cầu tạo tiến trình Pi ▪ Như vậy, thứ tự yêu cầu mà tiến trình Leader nhận khác với thứ tự chúng tạo ! 21 Bài tập ▪ Đề xuất cải tiến thuật toán mutex tập trung để thoả mãn thuộc tính cơng 22 Thuật tốn vịng trịn token ▪Giả sử tất tiến trình tổ chức theo hình trịn ▪Token lưu thơng quanh vịng trịn ▪Tiến trình Pi muốn vào CS phải chờ đến token luân chuyển đến ▪ Khi Pi bắt lấy token vào CS 23 public class CircToken extends Process implements Lock { public synchronized void initiate() { if (haveToken) sendToken(); } public synchronized void requestCS() { wantCS = true; while (!haveToken) myWait(); } public synchronized void releaseCS() { wantCS = false; sendToken(); } void sendToken() { } public synchronized void handleMsg(Msg m, int src, String tag) { if (tag.equals("token")) { haveToken = true; if (wantCS) notify(); else { Util.mySleep(1000); sendToken(); } } } } 24 Tài liệu tham khảo ▪ Concurrent and Distributed Computing in Java, Vijay K Garg, University of Texas, John Wiley & Sons, 2005 ▪ Tham khảo: ▪ Principles of Concurrent and Distributed Programming, M Ben-Ari, Second edition, 2006 ▪ Foundations of Multithreaded, Parallel, and Distributed Programming, Gregory R Andrews, University of Arizona, Addison-Wesley, 2000 ▪ The SR Programming Language: Concurrency in Practice, Benjamin/Cummings, 1993 ▪ Xử lý song song phân tán, Đoàn văn Ban, Nguyễn Mậu Hân, Nhà xuất Khoa học Kỹ thuật, 2009 25 ... gắn dấu thời gian tới tất tiến trình khác ▪ Đồng thời, Pi thêm u cầu có gắn dấu thời gian vào hàng đợi Khi tiến trình Pk nhận thơng điệp request từ tiến trình Pi ▪ Pk lưu yêu cầu dấu thời gian... (dùng để lưu dấu thời gian) Một hàng đợi Q (dùng để lưu yêu cầu vào CS tiến trình hệ thống phân tán) ▪ Thuật tốn đảm bảo: tiến trình vào CS theo thứ tự dấu thời gian yêu cầu phía tiến trình gửi ▪... q[i], q[j]: dấu thời gian yêu cầu vào CS hai tiến trình Pi Pj ▪ v[j]: dấu thời gian thông điệp xác nhận từ tiến tình Pj ghi nhận tiến trình Pi Các bước thực (1) Khi tiến trình Pi muốn vào CS ▪ Pi