You are on page 1of 17

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG

---------------o0o---------------

Báo cáo môn học:


Nguyên lý hệ điều hành

Chủ đề : Tìm hiểu một số bài toán về đồng bộ tiến trình qua đoạn găng

GVHD: Phạm Đăng Hải


SVTH: Nguyễn Hoàng Thành 20194378
Vũ Duy Hiệp 20194279
Đào Xuân An 20190076

TP. HÀ NỘI, THÁNG 12 NĂM 2021

1
Mục lục
1. Đường Ray ở Andes (Railways in the Andes).............................................. 3
2. Vấn đề của người hút thuốc lá(Cigarette Smoker’s Problem) ...................... 5
3. Ông già Noel (Bài toán Santa claus) ............................................................. 6
4. The dining savages problem ......................................................................... 8
5. Bài toán về “tìm kiếm – chèn – xóa” .......................................................... 11
6. Bài toán về “phòng tắm Unisex” ................................................................ 12
7. Bài toán quán ăn Sushi ................................................................................ 13
8. Bài toán chăm sóc trẻ .................................................................................. 15

2
1. Đường Ray ở Andes (Railways in the Andes)
Vấn đề thực tiễn
Một dãy núi cao ở Andes, ở đó có 2 tuyến đường sắt tròn. Một đường ở Peru, một
cái khác ở Bolivia. Họ cùng dùng chung , một phần của đường ray, nơi mà các
đường băng qua một đèo núi nằm trên biên giới quốc tế(Gần hồ Titicaca).

Thật không may mắn, các đoàn tàu của Peru và Bolivian thỉnh thoảng va chạm
nhau khi đồng thời đi vào phần chung của đường ray (đèo núi). Vấn đề là những
người lái xe của cả hai tàu đều bị mù và điếc, do đó họ không thể nhìn thấy hay
nghe thấy nhau.
Hai người lái tàu đã thống nhất về phương pháp ngăn ngừa va chạm sau đây. Họ
đặt một bát lớn ở lối vào đèo. Trước khi vượt qua, người lái xe phải dừng tàu, đi
qua bát, và chạm vào nó để thấy nó có chứa một tảng đá hay không. Nếu bát trống,
người lái xe phải tìm một hòn đá và bỏ nó vào bát, cho biết chuyến tàu của mình
đang đi qua; Một khi đoàn tàu của ông đã vượt qua được, ông phải đi bộ trở lại bát
và loại bỏ đá của ông, để báo hiệu rằng chỗ dùng chung đó không có ai sử dụng
nữa. Cuối cùng, anh ta quay trở lại tàu và tiếp tục lái xe.
Nếu người lái xe kia lái xe đến đèo tìm thấy trong bát có một hòn đá thì người đó
phải rời chỗ chung đường ray đó để tránh va chạm. Do vậy anh ta phải cho đoàn tài
nghỉ ngơi và kiểm tra lại cái tô cho đến khi thấy nó trống rỗng. Sau đó anh ta bỏ 1
hòn đá vào tô và cho tàu anh ta vào đèo. Một sinh viên thông minh đến từ đại học
LaPaz (Bolivia) cho rằng cái cách này có thể làm cho chặn đường tàu mãi mãi.
Nhưng người lái xe ở Bolivia chỉ cười và nói rằng điều đó không thể đúng bởi vì
nó không bao giờ xảy ra.
Thật không may, vào một ngày cả 2 đàu đâm vào nhau.
Sau vụ tai nạn. Sinh viên đó được gọi đến để tư vấn để đảm bảo răng sẽ không xảy
ra tai nạn nữa. Anh ấy nói rằng cái bát đã được sử dụng sai cách. Người lái xe ở
Bolivia phải đợi tại lối vào đèo cho đến khi cái bát trống, lái xe qua đèo và đi bộ
trở lại để đặt một tảng đá vào bát. Người lái xe người Peru phải chờ đến khi bát có
chứa đá, lái xe qua đèo và đi bộ để lấy tảng đá khỏi bát. Chắc chắn, phương pháp
của ông ngăn ngừa tai nạn. Trước khi sắp xếp này, tàu của Peru chạy hai lần một
ngày và tàu Bolivian chạy mỗi ngày một lần. Người Peru rất không hài lòng với
cách sắp xếp mới.
Do đó, sinh viên này được kêu gọi trở lại và được yêu cầu tìm giải pháp khác để
3
ngăn ngừa được tai nạn và tránh được vấn đề phương pháp trước đây. Sau một thời
gian suy nghĩ, sinh viên này đã đề nghị răng nên sử dụng 2 cái bát, một cho mỗi
người lái tàu, và cách thức hoạt động như sau: Khi lái xe đến chỗ vào đầu tiên anh
ta thả hòn đá vào tô của mình sau đó kiểm tra cái tô khác để xem nó có hòn đá nào
không. Nếu nó trống thì anh ta lái xe của mình thông qua đường chuyền. Sau đó
dừng lại và đi trở lại để loại bỏ hòn đá của mình. Nhưng nếu anh ta tìm thấy một
hòn đá trong bát khác thì anh ta trở lại bát của mình và lấy đá của mình ra.Tiếp
theo, anh ta nghỉ ngơi và đợi cho đến lúc cho cái bát kia trống rỗng và bỏ hòn đá
vào tô của mình... Phương pháp này hoạt động tốt cho đến cuối tháng 5, khi hai
chuyến tàu đồng thời bị chặn tại cửa khẩu.

Phân tích vấn đề:


Sau đây chúng ta cùng tìm hiểu thuật toán của bài toán này sao cho nó hiệu quả
nhất. Thực ra nếu để ý kĩ thì bạn thấy đây là một bài toán có dạng như producer-
consumer. Nhưng bây giờ chúng ta sẽ làm nó với signals và waits.
BINARYSEMAPHONE mutex=1
COUNTINSEMAPHORE empty = n; full=0;
Giải pháp:
Ta xem mutex là cái đèn báo, và ở đây ta quy về bài toán producer – consumer. Do
đó ta có thuật toán sau đây:
Procedure:

Customer:

4
2. Vấn đề của người hút thuốc lá(Cigarette Smoker’s
Problem)
Vấn đề thực tiễn:
Vấn đề này là do SS Patil vào năm 1971. Giả sử một điếu thuốc cần có ba thành
phần là thuốc lá, giấy và diêm. Có ba người hút thuốc dây chuyền. Mỗi người
trong số họ chỉ có một thành phần với nguồn cung cấp vô hạn. Có một đại lý có
nguồn cung cấp vô hạn của cả ba thành phần. Để tạo ra một điếu thuốc, người hút
thuốc lá ( tương ứng , giấy và diêm) phải có hai thành phần còn lại là giấy và diêm
( tương ứng., thuốc lá và diêm, thuốc lá và giấy). Người đại diện và người hút
thuốc ở chung một bàn. Tác nhân tạo ngẫu nhiên hai thành phần và thông báo cho
người hút cần hai thành phần này. Sau khi các thành phần được lấy ra khỏi bàn, đại
lý cung cấp hai nguyên liệu khác. Mặt khác, mỗi người hút thuốc đều chờ thông
báo của đại lý. Sau khi được thông báo, người hút sẽ chọn nguyên liệu, châm
thuốc, hút một lúc rồi quay lại bàn chờ nguyên liệu tiếp theo của mình.

Viết một chương trình mô phỏng hệ thống này, với ba người hút thuốc và tác nhân
được mô phỏng bằng các luồng.

Ví dụ: Người A có giấy, người B có thuốc lá, và người C có diêm . Nếu người đại
lý đưa ra giấy và thuốc(tobacco) thì người A và B sẽ không tạo được thuốc lá do
thiếu diêm.

Giải pháp (Solution):


Sau đây là một giải pháp khá dễ dàng . Cả 3 người sẽ làm được điếu thuốc lá và hút
nó. Nếu người nào không làm được điếu thuốc thì sẽ ngồi nghỉ 1 chỗ nào đó (Sleep)
. Khi người đại lý đặt hai vật lên trên bàn, và sẽ kêu (Wake up) người tương ứng có
thể tạo ra thuốc để hút, sau đó thì đi ngồi nghỉ tiếp. Sau đây sẽ là thuật toán giải
quyết vấn đề này.
Thuật toán cho người đại lý:

5
Thuật toán của người hút thuốc:

Người hút thuốc ngay lập tức ngủ, khi người đại lý đưa 2 vật lên bàn, sau đó đại lý
sẽ đánh thức người hút thuốc tương ứng. Người hút thuốc sau đó sẽ lấy đồ vật và
đánh thức các đại lý. Trong khi người hút thuốc lá đang hút, người đại lý có thể
đaẹt hai vật lên bàn và đánh thức một người khác (Nếu vật người đó có không
giống với 2 đồ vật trên bàn). Người đại lý ngủ ngay lập tức sau khi đặt các vật ra.
Giải thuật này giống với vấn đề Producer-Consumer .Ngoại trừ Producer chỉ có thể
sản xuất 1 mặt hàng (Mặc dù lựa chọn 3 mặt hàng) cùng 1 lúc.

3. Ông già Noel (Bài toán Santa claus)


Đây là một vấn đề được lấy từ sách Hệ điều hành của William. Nhưng được cho là
của ông John Trono, ở trường đại học Michael ở Vermont
Vấn đề thực tiễn:

6
Vấn đề này là do William Stallings’s Operating Systems [11], nhưng ông ấy quy nó
cho John Trono của Đại học St. Michael’s College ở Vermont.
Santa Claus đang ngủ ở trong cửa hàng của ông ấy ở Bắc Cực, ông ấy chỉ có thể
được đánh thức bởi:

1. Cả 9 con tuần lộc trở về từ kì nghỉ hè ở Thái Bình Dương


2. 3 trong số các chú lùn gặp khó khăn trong việc làm đồ chơi đến nhờ ông già
Noel giúp.
Một số lưu ý trong bài toán này:
o Khi 3 chú lùn đang nhờ ông già Noel giúp, bất kì chú lùn nào đến gặp
ông già Noel phải đợi những chú lùn kia trở về.
o Nếu ông già Noel thức dậy nhìn thấy 3 chú lùn ở ngoài cửa cùng với
con tuần lộc cuối cùng trở về từ vùng nhiệt đới thì những chú lùn có
thể phải đợi đến sau giáng sinh, bởi vì việc quan trọng lúc này là
chuẩn bị các xe trượt tuyết.
o Giả thiết rằng các con Tuần Lộc không muốn rời khỏi vùng nhiệt đới,
muốn ở lại đó đến giây phút cuối cùng có thể.
o Con Tuần Lộc cuối cùng đến nơi phải đón ông già Noel trong khi
những con khác chờ đợi trong một túp lều nóng lên trước khi được
đưa vào xe trượt tuyết.

Phân tích:
• Sau khi con tuần lộc thứ 9 đến, ông già noel phải chuẩn bị xe trượt tuyết
(prepareSleigh) , và sau đó cả 9 con tuần lộc phải được buộc dây thừng
(getHitched)
• Nếu trường hợp ông gìa Noel thức giấc chỉ có 3 chú lùn, ông già Noel phải
giúp đỡ các chú lùn (helpElves), và điều đó cũng có nghĩa là các chú lùn
được giúp đỡ (getHelp).
• Tất cả 3 chú lùn phải được giúp đỡ trước khi chú lùn nào khác được bổ
sung.

Giải pháp cho bài toán:


Khởi tạo

7
Ông già Noel (Santa Claus)

Reindeer

Elves

4. The dining savages problem


Vấn đề thực tiễn:

8
Vấn đề này từ quyển Concurrent Programming của Andrews.

Vấn đề man rợ trong ăn uống của Hệ điều hành với việc triển khai màn hình: Vấn
đề về sự man rợ trong ăn uống (ám chỉ đến các triết gia ăn uống cổ điển) dựa trên
sự tương tự vô vị được cho là của một số thành viên của nền văn hóa nguyên thủy,
sau đây được gọi là "sự man rợ", chia sẻ một bữa ăn từ một nồi duy nhất. Những
yếu tố trừu tượng chính là bản thân những người man rợ, một đầu bếp và một cái
nồi. Nồi chứa một số lượng nhất định các loại thực phẩm ngon lành (bản chất của
chúng sẽ để bạn tưởng tượng). Mỗi người trong số những người ăn chay có thể tự
do lấy một phần ăn ra khỏi nồi miễn là nồi không bị rỗng. Vì vậy, trước khi lấy
một phần ăn, một người dã man phải kiểm tra để đảm bảo rằng nồi không bị
rỗng. Trong trường hợp nồi bị cạn, người dã chiến phải đánh thức người nấu để đổ
lại nồi, sau đó tiếp tục đãi tiệc. Những kẻ man rợ, sau đó, chỉ có thể ăn khi nồi
chưa rỗng và người nấu chỉ có thể đổ đầy nồi khi nồi đã cạn.

Phân tích và giải pháp


Tất cả các thành viên của bộ tộc đều sử dụng hàm lấy thức ăn:

Một tiến trình nấu ăn sẽ chạy lệnh:

Điều kiện ràng buộc giữa các tiến trình là:

• Người không thể lấy thức ăn (chạy hàm getDervingFromPot()) nếu nồi rỗng.
• Đầu bếp chỉ có thể bỏ thêm thức ăn (chạy hàm putServingInPot())khi nồi
rỗng. Chúng ta sử dụng biến đếm servings để đếm số lượng thức ăn còn lại
trong nồi. Nếu servings =0 thì đầu bếp sẽ chạy hàm putServingInPot() . Đèn
bào emptyPot để chỉ nồi rỗng và fullPot để chỉ nồi đã đầy.

9
Người nấu ăn:

Khí có tín hiệu báo nồi đã rỗng thì cook sẽ thực hiện hàm
putServingsInPot() để đưa thêm thức ăn vào nồi. Khi nồi đầy sẽ chạy tiến
trình fullPot.signal().// Savage (người trong bộ tộc)

Mỗi thành viên trong bộ tộc sẽ phải đợi đèn hiệu mutex để được lấy thức ăn.
Nếu nhận thấy nồi rỗng thì sẽ đợi cho đến khi tín hiệu nồi đầy (fullPot) từ
tiến trình Cook để thiết lập biến chỉ số lượng thức ăn trong nồi là servings =
M và chạy tiếp chương trình. Mỗi tiến trình sẽ lấy một khẩu phần ăn từ nồi
và giảm biến đếm đi 1 đơn vị . Sau khi lấy xong tiến trình này sẽ trả lại
mutex cho các tiến trình đang đợi khác và thực hiện hàm eat().

10
5. Bài toán về “tìm kiếm – chèn – xóa”
Nguồn gốc :
Vấn đề này được đề cập đến trong quyển Concurrent Programming : Principle
and Practice của Gregory R.Andrew.
Mô tả : Người tìm kiếm, người chèn , người xóa chia sẻ quyền truy cập vào một
danh sách liên kết đơn. Người tìm kiếm chỉ kiểm tra nội danh sách, do đó chúng có
thể thực thi đồng thời với nhau. Người chèn thêm các nút mới vào cuối danh sách,
các nút được chèn cần phải được loại trừ lẫn nhau để ngăn cản hai người chèn
thêm vào hai nút vào cùng một thời điểm. Tuy nhiên, một nút có thể được kiểm tra
song song bởi một số lượng người tìm kiếm bất kỳ. Cuối cùng, người xóa xóa một
nút ở một vị trí bất kỳ trong danh sách. Quá trình xóa có thể được diễn ra trong bất
kỳ thời điểm nào. Sự xóa, sự tìm kiếm và sự chèn cần phải được loại trừ lẫn nhau.
Người lập trình viết code để giải quyết vấn đề loại trừ lẫn nhau mang tính phân loại
ba chiều này giữa người tìm kiếm, người chén và người xóa.

Cách xử lý :
+ Cài đặt: Các biến được sử dụng :
1 insertMutex = Semaphore (1)
2 noSearcher = Semaphore (1)
3 noInserter = Semaphore (1)
4 searchSwitch = Lightswitch ()
5 insertSwitch = Lightswitch ()
insertMutex đảm bảo chỉ có một người truy cập trong thời gian truy cập cho phép
của người đó
noSearcher và noInserter đảm bảo không có sự xuất hiện ngẫu nhiên của người
tìm kiếm và người chèn trong thời gian truy cập cho phép, nó giống như chìa khóa
vào cửa vậy, người xóa muốn truy cập phải có cả hai chìa khóa này.
searchSwitch và insertSwitch lần lượt là công cụ để người tìm kiếm và người
chèn kết thúc phiên làm việc của người xóa.
+Xử lý người tìm kiếm :
1 searchSwitch . wait ( noSearcher )
2 # critical section

11
3 searchSwitch . signal ( noSearcher )
Người tìm kiếm sẽ chỉ lo lắng về người xóa. Người tìm kiếm đầu tiên truy cập sẽ
lấy noSearcher, người cuối cùng đăng xuất giải phóng nó.

+Xử lý người chèn :


insertSwitch . wait ( noInserter )
insertMutex . wait ()
# critical section
insertMutex . signal ()
insertSwitch . signal ( noInserter )
Tương tự với người tìm kiếm, người chèn đầu tiên truy cập sẽ lấy noInserter,
người cuối cùng đăng xuất giải phóng nó. Người chèn và người tìm kiếm có thể
gặp vấn đề cạnh tranh đồng thời. Tuy nhiên, insertMutex đảm bảo chỉ một người
chèn có thể truy cập trong một khoảng thời gian nhất định.
+Xử lý người xóa :
noSearcher . wait ()
noInserter . wait ()
# critical section
noInserter . signal ()
noSearcher . signal ()
Người xóa giữ cả noInserter và noSearcher , điều này đảm bảo người xóa không
gặp cạnh tranh với người tìm kiếm cũng như người chèn.

6. Bài toán về “phòng tắm Unisex”


Nguồn gốc và mô tả :
Một người phụ nữ làm việc trong tầng hầm của một tòa nhà và phòng tắm gần
nhất dành cho phụ nữ cách cô ấy hai tầng, cô ấy đề nghị Uberboss chuyển phòng
tắm dành cho nam ở tầng trên thành phòng tắm chung nam nữ. Uberboss đồng ý,
tuy nhiên ông ta đưa ra các điều kiện về đồng bộ hóa như sau:
+Không được có nam và nữ vào phòng tắm cùng lúc

12
+Không được có nhiều hơn 3 nhân viên công ty đi tắm cùng lúc

Cách xử lý :
+Cài đặt: Các biến được sử dụng:
1 empty = Semaphore (1)
2 maleSwitch = Lightswitch ()
3 femaleSwitch = Lightswitch ()
4 maleMultiplex = Semaphore (3)
5 femaleMultiplex = Semaphore (3)
empty mang giá trị 1 nếu phòng tắm đang trống và 0 nếu ngược lại
maleSwitch cho phép nam giới yêu cầu nữ giới ra khỏi phòng.
Khi người đàn ông đầu tiên vào phòng tắm, lightSwitch khóa biến empty, làm
người phụ nữ không được vào phòng
Khi người đàn ông cuối cùng bước ra, biến empty được giải phóng, cho phép
người phụ nữ vào phòng
femaleSwitch có chức năng tương tự đối với phụ nữ
maleMultiplex và femaleMultiplex đảm bảo không có nhiều hơn 3 người đi tắm
cùng lúc
+Xử lý nữ giới:
femaleSwitch . lock ( empty )
femaleMultiplex . wait ()
femaleMultiplex . signal ()
female Switch . unlock ( empty )
+Xử lý nam giới:
maleSwitch . lock ( empty )
maleMultiplex . wait ()
maleMultiplex . signal ()
male Switch . unlock ( empty )

7. Bài toán quán ăn Sushi

13
Nguồn gốc :
Bài toán này được phát triển dựa trên một vấn đề do Kenneth Reek đưa ra
Mô tả : Giả sử có một quán ăn Sushi với 5 chỗ ngồi. Nếu bạn đến quán khi đang có
một chỗ ngồi trống, bạn có thể ngồi đó ngay lập tức. Tuy nhiên, nếu không còn chỗ
ngồi trống nào, bạn cần phải chờ đến khi có người rời đi.

Cách xử lý :
+Cài đặt: Các biến được sử dụng :
1 eating = waiting = 0
2 mutex = Semaphore (1)
3 block = Semaphore (0)
4 must_wait = False
eating và waiting cho khách thấy số người đang ăn và số người trên hàng đợi
mutex bảo vệ 2 biến trên khỏi việc bị đá khỏi hàng đợi
must_wait cho khách biết quán ăn đang đầy chỗ ngồi
những vị khách đang đến quán khi hàng đợi đang đầy bị block bởi biến block
+Xử lý vấn đề :
mutex . wait ()
if must_wait :
waiting += 1
mutex . signal ()
block . wait ()
else :
eating += 1
must_wait = ( eating == 5)
mutex . signal ()
mutex . wait ()
eating -= 1
if eating == 0:

14
n = min (5 , waiting )
waiting -= n
eating += n
must_wait = ( eating == 5)
block . signal (n)
mutex . signal ()
Khi khách hàng cuối cùng rời đi, giải phóng biến mutex, biến eating được cập nhật,
những khách hàng mới đến sẽ thấy trạng thái phù hợp và block nếu cần thiết. Một
hạn chế của phương pháp này là việc cập nhật trạng thái hơi phức tạp một chút.

8. Bài toán chăm sóc trẻ


Nguồn gốc :
Vấn đề này được đề cập trong sách Operating Systems and Middleware:
Supporting Controlled Interaction của tác giả Max Hailperin
Mô tả : Tại một trung tâm giữ trẻ, tiểu bang quy định cứ 3 đứa trẻ phải được một
người lớn chăm sóc.Số lượng người lớn rời đi có thể ngăn chặn số lượng trẻ bước
vào. Người lập trình viết code thực thi sự ràng buộc này trong một section

Cách xử lý :
+Cài đặt : Các biến được sử dụng :
1 children = adults = waiting = leaving = 0
2 mutex = Semaphore (1)
3 childQueue = Semaphore (0)
4 adultQueue = Semaphore (0)
children, adults, waiting và leaving đếm số lượng trẻ em, người lớn hiện tại, số
lượng trẻ em sắp bước vào và số lượng người lớn sắp rời đi. Mutex bảo vệ các
biến này. Trẻ em chờ trên childQueue để bước vào nếu cần thiết. Người lớn chờ
trên adultQueue để rời đi.
+Xử lý trẻ em:
mutex . wait ()
if children < 3 * adults :
children ++
15
mutex . signal ()
else :
waiting ++
mutex . signal ()
childQueue . wait ()
# critical section
mutex . wait ()
children –
if leaving and children <= 3 * ( adults -1):
leaving –
adults –
adultQueue . signal ()
mutex . signal ()
Khi một đứa trẻ muốn bước vào, hệ thống check xem đủ số người lớn chưa. Nếu
đã đủ, tăng biến children lên, ngược lại tăng biến waiting và block.
+Xử lý người lớn:
mutex . wait ()
adults ++
if waiting :
n = min (3 , waiting )
childQueue . signal (n)
waiting -= n
children += n
mutex . signal ()
# critical section
mutex . wait ()
if children <= 3 * ( adults -1):
adults –

16
mutex . signal ()
else :
leaving ++
mutex . signal ()
adultQueue . wait ()
Khi người lớn bước vào, họ đưa đèn báo cho những đứa trẻ trong waiting nếu có.
Trước khi họ rời đi, họ phải check biến adult .Nếu số người lớn hiện tại đủ, giảm
biến adult, ngược lại, tăng biến leaving và block.

17

You might also like