Chú ý: Java không cung cấp các cột để xây dựng ngôn ngữ cơ bản, nhưng có thể dễ dàng được thực thi trong Java bằng cách sử dụng ý tưởng của các Monitor sẽ đề cập sau.. Bài toán Bộ đọ
Trang 1ĐỒNG BỘ HOÁ NGUYÊN THUỶ
Giảng viên hướng dẫn: PGS.TS Trần Đình Quế
Học viên thực hiện:
Bùi Hồng Đại Nguyễn Thị Bích Ngọc Phạm Hữu Tình
Phạm Minh Tuấn Nguyễn Tuấn
Trang 23.2.2 Bài toán Bộ đọc – Bộ ghi (The Reader-Writer Problem)
3.2.3 Bài toán các triết gia ăn tối (The Dining Philosopher Problem)
3.3 Monitors
3.4 Nguy hiểm của sự tắc nghẽn (DANGERS OF DEADLOCKS)
3.5 Problems
3.6 Bibliographic Remarks
Trang 4 Các thao tác này được đặt tên P () (cho wait - chờ để kiểm tra)
và V () (cho signal- báo hiệu để tăng).
Giá trị của Semaphore (hoặc Semaphore nhị phân) chỉ có thể
là sai hoặc đúng.
Hàng đợi của các quá trình bị chặn ban đầu là trống rỗng
một quá trình có thể thêm vào hàng đợi khi nó làm cho một cuộc gọi đến P ().
Khi một quá trình gọi P () và giá trị là đúng, thì giá trị của cột trở thành sai.
Nếu giá trị của cột là sai, sau đó quá trình này bị chặn cho đến khi nó trở thành đúng
Bùi
Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 5Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 6 Loại trừ lẫn nhau là đơn giản để thực hiện:
BinarySernaphore mutex = new BinarySemaphore(true1;
mutex.P();
c r i t i c a l S e c t i o n 0 ; mutex.V();
Một biến thể của cột cho phép nó để có bất kỳ số
nguyên giá trị của nó.
Các cột này được gọi là Semaphores đếm
Trang 7 Chú ý:
Java không cung cấp các cột để xây dựng ngôn ngữ cơ bản, nhưng có thể dễ dàng được thực thi trong Java bằng cách sử dụng ý tưởng của các Monitor (sẽ đề cập sau).
Chỉ đơn giản cho rằng Semaphores có sẵn và giải quyết vấn đề đồng bộ hóa bằng cách sử dụng
chúng.
Bùi
Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 8gia ăn ăn tối tối
Trang 9Bài toán Nhà sản xuất – Người tiêu thụ
Một bộ đệm được chia sẻ giữa hai quá trình được gọi là nhà sản xuất và người tiêu thụ
Nhà sản xuất sản xuất các mục được gửi trong bộ đệm và người tiêu thụ lấy các mục từ bộ đệm và tiêu thụ (sử dụng) chúng
Giả sử các mặt hàng kiểu Double Kể từ khi bộ đệm được chia sẻ, mỗi quá trình phải truy cập vào bộ
đệm trong một cách loại trừ lẫn nhau.
Sử dụng một loạt các đôi kích thước như một bộ
đệm của chúng
Bùi
Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 10Bài toán Nhà sản xuất – Người tiêu thụ
Bộ đệm có hai con trỏ, inBuf và outBuf, các chỉ số trong mảng gửi một mục và lấy một mục tương ứng
Biến đếm theo dõi số lượng các mục hiện trong bộ đệm
bên cạnh việc loại trừ lẫn nhau, có thêm hai hạn chế
đồng bộ hóa mà cần phải được thỏa mãn:
Người tiêu dùng không nên lấy bất kỳ mục nào từ
một bộ đệm trống.
Nhà sản xuất không nên gửi bất kỳ mục nào trong bộ đệm nếu nó là đầy đủ Các bộ đệm có thể trở thành đầy đủ nếu nhà sản xuất là sản xuất các mặt hàng tại một tỷ lệ lớn hơn so với tỷ lệ mà tại đó các mặt hàng được tiêu thụ của người tiêu dùng.
Bùi
Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 11Bài toán Nhà sản xuất – Người tiêu thụ
điều kiện đồng bộ hóa.
điều kiện để trở thành hiện thực (chẳng hạn như các bộ đệm để trở thành không rỗng)
trước khi tiếp tục các hoạt động của mình.
Bùi
Bùi Hồng Hồng Đại Đại – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 12Bài toán Bộ đọc – Bộ ghi
truy cập vào cơ sở dữ liệu chia sẻ Yêu cầu bao gồm:
đảm bảo rằng người đọc và người viết không truy cập CSDL đồng thời.
đảm bảo rằng 2 người ghi không truy cập CSDL đồng thời.
Nguyễn
Nguyễn Thị Thị Bích Bích Ngọc Ngọc – – M12CQCT01 M12CQCT01 B B GROUP 1
Trang 13Bài toán Bộ đọc – Bộ ghi
Có thể đồng thời nhiều người đọc truy cập vào
CSDL đồng thời
giả sử rằng người đọc theo dõi giao thức bằng cách
họ gọi hàm startRead trước khi đọc CSDL và gọi
hàm endRead sau khi đọc xong
Người ghi theo dõi với giao thức tương tự
dụng wlock semaphores để đảm bảo rằng chỉ có
người ghi đơn lẻ truy cập vào CSDL và chỉ có những người đọc truy cập vào nó Để đếm số lượng người đọc truy cập vào CSDL, chúng ta sử dụng hàm
numReaders.
www.themegallery.com Company Logo
Trang 14Bài toán Bộ đọc – Bộ ghi
Phương thức startWrite và endWrite là khá đơn
người ghi có thể truy cập vào CSDL cho đến khi
người ghi này gỡ bỏ việc khóa sử dụng hàm
endWrite().
www.themegallery.com Company Logo
Trang 15Bài toán Bộ đọc – Bộ ghi
Xem hàm startRead và endRead
Trong hàm startRead, người đọc đầu tiên gia tăng
numReaders Nếu đây là người đọc đầu tiên (numReaders = 1) , sau đó nó cần khóa CSDL, nếu không sẽ có những người đọc khác truy cập vào CSDL và có thể sử dụng nó
Trong hàm endRead, giá trị của numRead giảm dần và khi người đọc cuối cùng rời khỏi CSDL thì CSDL sẽ được mở khóa và sử dụng gọi hàm wlock.V().
Giao thức này có sự bất lợi đó là người ghi có thể bị bỏ đói trong sự có mặt liên tục của người đọc Một giải pháp starvation – free cho vẫn đề đọc – ghi vẫn còn là một bài tập
www.themegallery.com Company Logo
Trang 16Bài toán các triết gia ăn tối
Vấn đề này, đầu tiên đặt ra và giải quyết bằng cách
Dijkstra, có ích trong việc đưa ra khỏi vấn đề liên quan
với lập trình đồng thời và đối xứng
yêu cầu đưa ra 1 giao thức để phối hợp truy cập vào các tài nguyên chia sẻ Một người có đầu óc máy tính có thể thay thế cho quy trình triết học và tập tin cho các đĩa
Nhiệm vụ ăn uống có thể xem như là phản hồi của hoạt động yêu cầu truy nhập đến file chia sẻ
Mỗi triết gia Pi lặp lại một cách xoay vòng các trạng thái được theo dõi như sau: thinking, hungry và eating Để
ăn, triết gia cần có các tài nguyên (dĩa) do đó cần gọi
hàm acquire(i) Do đó giao thức yêu cầu trừu tượng hóa một giao diện Resource
www.themegallery.com Company Logo
Trang 17Bài toán các triết gia ăn tối
Để giải quyết vấn đề này sử dụng nhị phân
semaphores cho mỗi chiếc dĩa.
Để yêu cầu các nguồn tài nguyên để ăn, một nhà
triết học i sẽ túm lấy chiếc dĩa ở bên trái bằng cách
sử dụng fork[i] P() và dĩa bên phải sử dụng
người hàng xóm bên phải đặt lại dĩa đó.
www.themegallery.com Company Logo
Trang 18Bài toán các triết gia ăn tối
Có nhiều cách để mở ra hướng giải quyết đảm bảo giải phóng bế tắc Ví dụ:
Chúng ta có thể giới thiệu đối xứng bằng cách yêu
cầu một người triết gia túm lấy chiếc dĩa trong một thứ tự khác nhau ( ví dụ: dĩa bên phải cho phép bởi dĩa bên trái thay vì ngược lại).
Chúng ta có thể yêu cầu triết gia cầm cả 2 dĩa lên tại thời điểm đồng thời.
Giả sử nhà triết gia có thể đứng lên trước khi cầm bất
cứ dĩa nào Cho phép nhiều nhất 4 triết gia tại bất cứ thời điểm nào.
Đây như là bài tập để người đọc thiết kế giao thức để
giải phóng bế tắc
www.themegallery.com Company Logo
Trang 19Bài toán các triết gia ăn tối
họa sự khác biệt giữa bế tắc tự do và bế tắc đói.
Giả sử yêu cầu triết gia cầm cả 2 dĩa tại thời điểm đồng thời Mặc dù lúc này có thể loại
bỏ bế tắc
Sẽ có vấn đề với các triết gia đang đói bởi vì hàng xóm tiếp tục luân phiên nhau ăn Người đọc được mời đến với giải pháp là tự do bế tắc tốt hơn là bị đói.
www.themegallery.com Company Logo
Trang 20 Monitor là một cấu trúc hướng đối tượng bậc cao
để đồng bộ hóa trong lập trình đồng thời
Monitor có thể được xem như một lớp (Class) mà
có thể được sử dụng trong chương trình đồng thời
một Monitor có các biến dữ liệu (variables) và
phương pháp (methods) để thao tác dữ liệu Bởi vì nhiều luồng (threads) có thể truy cập dữ liệu được chia sẻ cùng một lúc
Monitor hỗ trợ methods để đảm bảo loại trừ lẫn
nhau (mutual exclusion)
www.themegallery.com Company Logo
Trang 21 Điều kiện là ít nhất một threads có thể được thực hiện
trong bất kỳ methods nào và bất cứ lúc nào.
Cụm từ " thread t is inside the monitor " được sử dụng để biểu thị rằng thread t được thực hiện bên trong monitor
Nhiều nhất là một thread có thể được ỏ trong monitor tại
một thời điển bất kỳ
Như vậy, liên quan đến tất cả các đối tượng monitor là một danh sách các thread đang chờ đợi để vào monitor
Đối tượng monitor là một tài nguyên sử dụng chung còn
các Thread như là các tiến trình chờ đợi để được sử dụng tài nguyên chung.
Tại một thời điểm bất kỳ chỉ có 1 thread có thể được sử
dụng tài nguyên chung là monitor).
www.themegallery.com Company Logo
Trang 22 Chương trình đồng thời cũng yêu cầu đồng bộ hóa có điều
kiện (conditional synchronization) khi một threads phải chờ
đợi một điều kiện nhất định để trở thành hiện thực
Để giải quyết đồng bộ có điều kiện, Monitor hỗ trợ xây dựng
các khái niệm về biến điều kiện (condition variables) Một biến
điều kiện có hai hoạt động được xác định trên nó: chờ đợi
(wait) và thông báo (notify) (còn được gọi là signal)
Đối với bất kỳ điều kiện biến x:
Với mọi thread t1, mà gọi đến x.wait () thì thread t1 bị chặn
và đưa vào một hàng đợi kết hợp với x.
Khi thread khác t2, gọi đến x.notify (), nếu hàng đợi kết hợp với x là rỗng, một thread được lấy ra từ hàng đợi và đưa vào hàng đợi của các thread có đủ điều kiện để chạy.
www.themegallery.com Company Logo
Trang 23được chờ đợi Có hai câu trả lời có thể sảy ra:
Một trong những thread đã được chờ đợi trên biến
điều kiện tiếp tục thực hiện monitor theo quy tắc này được gọi là Hoare monitor
Các thread đó thực hiện cuộc gọi thông báo cho tiếp tục thực hiện Khi thread này đi ra khỏi monitor, sau
đó các thread khác có thể nhập vào monitor Đây là ngữ nghĩa sau trong Java (the semantics followed in Java)
www.themegallery.com Company Logo
Trang 24khi thông báo (notify), nó có thể cho rằng điều kiện là
đúng Vì vậy, bằng cách sử dụng Hoare Mointor, mã của một thread có thể là: if (!B) x.wait();
Giả sử rằng t2 thông báo chỉ khi B là đúng, chúng ta biết rằng t1 có thể giả định B thay đổi Trong Java kiểu
monitor, mặc dù t2 phát hành thông báo, t1 vẫn tiếp tục thực hiện Vì vậy, khi t1 được được thực hiện, các điều kiện B có thể không đúng nữa Do đó, khi sử dụng Java, các thread thường chờ đợi điều kiện này như: while(!B) x.wait();
www.themegallery.com Company Logo
Trang 25 Các thread t1 có thể chỉ lấy một notify() như một gợi ý
rằng B có thể đúng Do đó, rõ ràng cần phải kiểm B khi thay đổi Nếu B thực sự là sai, nó gọi lại wait().
Trong Java, chúng ta xác định một đối tượng là một
monitor bằng cách sử dụng các từ khóa đồng bộ với các phương pháp của nó Để có được đồng bộ hóa có điều kiện, Java cung cấp:
wait(): chèn các thread trong hàng đợi Để đơn giản, chúng tôi sử dụng Util.myWait () thay vì wait () trong Java Sự khác biệt duy nhất là myWait () bắt được ngoại lệ bị gián đoạn( InterruptedException)
notify (): đánh thức một thread trong hàng đợi.
notifyAll (): đánh thức tất cả các thread trong hàng
đợi chờ.
www.themegallery.com Company Logo
Trang 26 Java không có biến điều kiện Như vậy, kết hợp với mỗi đối tượng có một hàng đợi duy nhất cho điều kiện.
Điều này là đủ cho hầu hết nhu cầu lập trình.
Nếu cần, nó cũng dễ dàng để mô phỏng các biến điều
kiện trong Java Một đại diện bằng hình ảnh của một
Java monitor.
Có hai hàng đợi kết hợp với một đối tượng: một hàng đợi của các thread chờ khóa liên quan đến monitor và một hàng đợi của các thread chờ đợi một số điều kiện để trở thành hiện thực
www.themegallery.com Company Logo
Trang 27Nguy hiểm của sự tắc nghẽn
(Deadlock)
để xảy ra quá trình tắc nghẽn (Deadlock).
xuyên chiến lược đặt tất cả các đối tượng trong một hệ thống và thu được duy nhất một lock trong đơn tăng thêm
t2.interrupt(), t2 sẽ get InterruptedException.
khác Nó không yêu cầu một ngắt nào với các thread khác và một chương trình không có yield() sẽ có chức năng tương đương với gọi yield() Một thread có thể chọn yield() nếu nó đang đợi cho dữ liệu để sẵn sàng từ InputStream.
đang sử dụng giám sát lock của đối tượng x.
www.themegallery.com Company Logo
Trang 28Các vấn đề
thi tự động, khi đó các kết thúc có thể bị vi phạm
dụng nhị phân (Gợi ý: sử dụng các biến chia sẻ kiểu integer và
semaphore hai nhị phân.
semaphore.
thread gọi là barbe Barber sẽ chặn lại sự đợi chờ của bất cứ
customer nào Nếu không có customer, barber sẽ ngừng làm việc Nếu
có nhiều thread customer Một customer sẽ đợi barber nếu có bất cứ ghế bên trái trong barber room Ngược lại, customer rời ngay lập tức Nếu có một chair trống, customer sẽ chiếm đóng Nếu barber đang
ngủ, customer sẽ đánh thưc barber dậy giả sử rằng có n ghế trong
barber shop Viết một lớp Java SleepingBarber swrr dụng semaphore cho phép những phương thức sau: runBarber() // gọi thread barber; chạy mãi mai; hairCut() // gọi thread customer
www.themegallery.com Company Logo
Trang 29Các vấn đề
3.5 Đưa một giải pháp deadlock-free cho vấn đề
dùng bữa tối sử dụng semaphore Giả sử rằng một trong số các chiếc dĩa được chọn là khác nhau.
3.6 Giả sử rằng có ba threads – P, Q và R Sử dụng semaphore để điều hành in ấn như là số của R được
in ra luôn nhỏ hơn hoặc bằng tổng số của P và Q
được in ra.
3.7 Viết một giám sát cho vấn đề sleeping barber
3.8 Chỉ ra cách điều khiển các biến của một giám sát
có thể thực thi trong Java
www.themegallery.com Company Logo
Trang 30phương thức: increment() và decrement() Kết quả
của việc giảm giá trị nhỏ nhất và tăng giá trị lớn nhất trong việc gọi thread đợi đến khi thao tác được thực hiện mà không xâm phạm vào phạm vi đếm
www.themegallery.com Company Logo
Trang 31Bình luận thư mục
[Dij65a] Khái niệm giám sát được giới thiệu bởi Brinch Hansen [Ha11721 và Hoare-
phong cách giám sát, bởi Hoare [Hoa74].
cổ điển trong Java cũng sẽ được thảo luận
trong cuốn sách của Hartley [Har98] Ví dụ
của bế tắc và độ phân giải của nó dựa trên
nguồn tài nguyên đặt hàng được thảo luận
trong cuốn sách của Lea [Lea99].
www.themegallery.com Company Logo
Trang 32LOGO