Bài toỏn triết gia ăncơm

Một phần của tài liệu Bao cao mon hoc he dieu hanh (Trang 75)

5 .4Một số bài toỏn đồng bộ

5.4.1 Bài toỏn triết gia ăncơm

// chạy đồng thời 5 tiến trỡnh StartProcess(Philosopher(1)); ...

StartProcess(Philosopher (5)); }

Tỡnh huống trong bài toỏn như sau. Cú năm triết gia ngồi trờn ghế quanh một bàn trũn, giữa bàn là thức ăn, xung quanh bàn cú năm chiếc đũa sao cho bờn phải mỗi người cú một đũa và bờn trỏi cú một đũa (hỡnh 33).

Cụng việc của mỗi triết gia là suy nghĩ. Khi người nào đú cần ăn, người đú dừng suy nghĩ, nhặt hai chiếc đũa nằm gần hai phớa và ăn. Triết gia cú thể nhặt hai chiếc đũa theo thứ tự bất kỳ nhưng bắt buộc phải nhặt từng chiếc một với điều kiện đũa khụng nằm trong tay người khỏc. Sau khi cầm được cả hai đũa, triết gia bắt đầu ăn và khụng đặt đũa xuống trong thời gian ăn. Sau khi ăn xong, triết gia đặt hai đũa xuống bàn và suy nghĩ tiếp.

Cú thể coi năm triết gia như năm tiến trỡnh đồng thời với tài nguyờn nguy hiểm là đũa và đoạn nguy hiểm là đoạn dựng đũa để ăn.

Cờ hiệu cho phộp giải quyết bài toỏn này như sau. Mỗi đũa được biểu diễn bằng một cờ hiệu. Thao tỏc nhặt đũa sẽ gọi Wait đối với cờ hiệu tương ứng và thao tỏc đặt đũa xuống bàn gọi Signal. Toàn bộ giải phỏp sử dụng cờ hiệu cho bài toỏn triết gia ăn cơm thể hiện trờn 33 Lưu ý rằng giải phỏp trờn 34 cho phộp thực hiện loại trừ tương hỗ, tức là trỏnh trường hợp hai triết gia cựng nhặt một đũa. Tuy nhiờn, giải phỏp này cú thể gõy bế tắc nếu cả năm người cựng nhặt được đũa bờn trỏi và khụng thể tiếp tục vỡ đũa bờn phải đó bị người bờn phải nhặt mất. Cỏch giải quyết tỡnh trạng này sẽ được đề cập trong phần về bế tắc.

5.4.2 Bài toỏn ngƣời sản xuất, ngƣời tiờu dựng với bộ đệm hạn chế

Bài toỏn được mụ tả như sau. Cú một người sản xuất ra sản phẩm gỡ đú và xếp sản phẩm làm ra vào một chỗ chứa gọi là bộ đệm, mỗi lần một sản phẩm. Một người tiờu dựng lấy sản phẩm từ bộ đệm, mỗi lần một sản phẩm, để sử dụng. Dung lượng của bộ đệm là hạn chế và chỉ chứa được tối đa N sản phẩm. Đõy là bài toỏn cú nhiều phiờn bản tương tự trờn thực tế, chẳng hạn thiết bị vào ra như bàn phớm cú thể nhận ký tự gừ từ bàn phớm, đặt vào bộ đệm, và tiến trỡnh lấy ký tự từ bộ đệm ra để xử lý. Trong trường hợp tổng quỏt cú thể cú nhiều người sản xuất cựng làm ra và xếp sản phẩm vào bộ đệm.

Bài toỏn người sản xuất người tiờu dựng đặt ra ba yờu cầu đồng bộ sau:

- Người sản xuất và người tiờu dựng khụng được sử dụng bộ đệm cựng một lỳc. Đõy là yờu cầu loại trừ tương hỗ.

- Khi bộ đệm rỗng, người tiờu dựng khụng nờn cố lấy sản phẩm.

- Khi bộ đệm đầy, người sản xuất khụng được thờm sản phẩm vào bộ đệm.

Ba yờu cầu trờn cú thể giải quyết bằng cờ hiệu. Yờu cầu thứ nhất được giải quyết bằng cỏch sử dụng một cờ hiệu lock khởi tạo bằng 1. Yờu cầu thứ hai và thứ ba được giải quyết lần lượt

signal (empty); } } void consumer () for (;;) {

{ //tiến trỡnh người tiờu

dựng wait (empty); wait (lock); <lấy một sản phẩm từ bộ đệm> signal (lock); signal (full); <tiờu dựng> } } void main(){ StartProcess(producer); StartProcess(consumer); }

bằng hai cờ hiệu empty và full. Cờ hiệu emptyđược khởi tạo bằng 0 và full được khởi tạo bằng kớch thước bộ đệm N. Giải phỏp cho bài toỏn được thể hiện trờn 5.12:

5.5 Monitor

Trong một phần trước ta đó xem xột về cơ chế đồng bộ sử dụng cờ hiệu. Mặc dự cú một số ưu điểm như khụng phải chờ đợi tớch cực và dễ sử dụng hơn giải thuật Peterson song đồng bộ

const int N; //kớch thước bộ đệm

semaphore lock = 1; semaphore empty = 0; semaphore full = N;

void producer () { //tiến trỡnh người sản xuất

for (;;) { <sản xuất > wait (full); wait (lock); <thờm một sản phẩm vào bộ đệm> signal (lock);

húa bằng cờ hiệu cú thể gõy ra lỗi nếu khụng được sử dụng đỳng cỏch. Sử dụng cờ hiệu khụng đỳng sẽ gõy ra cỏc lỗi sau:

- Quờn khụng gọi thao tỏc wait hoặc signal hoặc cả hai.

- Đảo ngược thứ tự wait và signal: gõy ra bế tắc.

Thay vỡ dựng thao tỏc wait lại dựng signal hoặc ngược lại, tức là gọi wait hai lần hoặc signal hai lần: trong trường hợp thứ nhất khụng đảm bảo loại trừ tương hỗ, trong trường hợp thứ hai gõy đúi.

Một điều quan trọng là những lỗi xuất hiện như vậy khú debug do lỗi chỉ xẩy ra ở một số trường hợp khi tiến trỡnh thực hiện xen kẽ nhau theo một thứ tự nhất định.

Để hạn chế phần nào cỏc vấn đề vừa nờu khi sử dụng cờ hiệu, một giải phỏp khỏc của nhúm giải phỏp dựa trờn hỗ trợ của hệ điều hành và ngụn ngữ bậc cao là giải phỏp sử dụng monitor (một số tài liệu tại Việt nam dịch là phũng đợi do đặc điểm của monitor).

5.5.1 Khỏi niệm monitor

Monitor được định nghĩa dưới dạng một kiểu dữ liệu trừu tượng của ngụn ngữ lập trỡnh bậc cao, chẳng hạn như một class của C++ hoặc Java. Mỗi monitor gồm một dữ liệu riờng, hàm khởi tạo, và một số hàm hoặc phương thức để truy cập dữ liệu với cỏc đặc điểm sau:

1) Tiến trỡnh hoặc dũng chỉ cú thể truy cập dữ liệu của monitor thụng qua cỏc hàm hoặc phương thức của monitor, khụng thể truy cập dữ liệu trực tiếp. Tiến trỡnh thực hiện trong monitor bằng cỏch gọi hàm do monitor cung cấp.

2) Tại mỗi thời điểm, chỉ một tiến trỡnh được thực hiện trong monitor. Tiến trỡnh khỏc gọi hàm của monitor sẽ bị phong tỏa, xếp vào hàng đợi của monitor để chờ cho đến khi monitor được giải phúng.

Đặc điểm thứ nhất rất quen thuộc đối với đối tượng trong ngụn ngữ lập trỡnh hướng đối tượng và làm cho monitor cú nhiều điểm tương tự class.

Đặc điểm thứ hai cho phộp đảm bảo loại trừ tương hỗ đối với đoạn nguy hiểm. Người lập trỡnh chỉ cần đặt tài nguyờn nguy hiểm vào trong monitor, vớ dụ đặt biến dựng chung thành dữ liệu của monitor, và khụng cần lập trỡnh cơ chế loại trừ tương hỗ một cỏch tường minh bằng cỏch sử dụng cỏc bước trước và sau đoạn nguy hiểm như trong những phương phỏp ở trờn. Đặc điểm này giỳp trỏnh lỗi xảy như khi dựng cờ hiệu.

5.5.2 Biến điều kiện

Monitor được định nghĩa như trờn cho phộp giải quyết vấn đề loại trừ tương hỗ. Tuy nhiờn, cú thể xẩy ra vấn đề khỏc về đồng bộ, chẳng hạn khi một tiến trỡnh đang thực hiện trong monitor và phải dừng lại (bị phong tỏa) để đợi một sự kiện hay một điều kiện nào đú được thỏa món. Trong trường hợp như vậy, tiến trỡnh cần trả lại monitor để tiến trỡnh khỏc cú thể sử dụng. Tiến trỡnh chờ đợi sẽ được khụi phục lại từ điểm dừng sau khi điều kiện đang chờ đợi được thỏa món.

Để giải quyết tỡnh huống vừa nờu, ta cú thể sử dụng cỏc biến điều kiện. Đõy là những biến được khai bỏo và sử dụng trong monitor với hai thao tỏc là cwait và csignal (tiền tố “c” được thờm vào để phõn biệt với cờ hiệu) như sau:

- x.cwait (): tiến trỡnh đang ở trong monitor và gọi cwait bị phong tỏa cho tới khi điều kiện x xẩy ra. Tiến trỡnh bị xếp vào hàng đợi của biến điều kiện x. Monitor được giải phúng và một tiến trỡnh khỏc sẽ được vào monitor.

- x.csignal (): tiến trỡnh gọi csignal để thụng bỏo điều kiện x đó thỏa món. Nếu cú tiến trỡnh đang bị phong tỏa và nằm trong hàng đợi của x do gọi x.cwait() trước đú thỡ một tiến trỡnh như vậy sẽ được giải phúng. Nếu khụng cú tiến trỡnh bị phong tỏa thỡ thao tỏc csignal sẽ khụng cú tỏc dụng gỡ cả.

Cần lưu ý điểm khỏc nhau của csignal với signal của cờ hiệu: signal luụn giải phúng một tiến trỡnh cũn csignal thỡ cú thể khụng, nếu khụng cú tiến trỡnh chờ đợi điều kiện.

Cấu trỳc monitor với cỏc biến điều kiện được thể hiện trờn 35

Hỡnh 35 Monitor

Để minh họa cho cỏch sử dụng monitor, chỳng ta sẽ xem xột một giải phỏp cho bài toỏn người sản xuất người tiờu dựng với bộ đệm hạn chế, trong đú cơ chế đồng bộ được thực hiện bằng monitor (hỡnh 2.20). Trong giải phỏp này, bộ đệm buffer được khai bỏo như dữ liệu cục bộ của monitor cú thể truy cập bằng hai thao tỏc append (thờm vào) và take (lấy ra). Monitor sử dụng hai biến điều kiện notFull và notEmpty để trỏnh việc thờm sản phẩm vào bộ đệm đầy hoặc lấy sản phẩm khỏi bộ đệm rỗng.

monitor BoundedBuffer {

product buffer[N]; //bộ đệm chứa N sản phẩm kiểu product

int count; //số lượng sản phẩm hiện thời trong bộ đệm

condition notFull, notEmpty; //cỏc biến điều kiện

public:

BoundedBuffer( ) { //khởi tạo

count = 0; }

void append (product x) { if (count == N)

notFull.cwait ( ); //dừng và chờ đến khi buffer cú chỗ

<Thờm một sản phẩm vào buffer> count++; notEmpty.csignal (); } product take ( ) { if (count == 0)

notEmptry.cwait (); //chờ đến khi buffer khụng rỗng

notFull.csignal ( ); }

}

void producer ( ) for (;;){

{ //tiến trỡnh người sản xuất

<Sản xuất sản phẩm x> BoundedBuffer.append (x); } } void consumer ( ) for (;;){

{ //tiến trỡnh người tiờu dựng

product x = BoundedBuffer.take (); <Tiờu dựng x>

} }

void main() {

Thực hiện song song producer và consumer. }

5.6 Semaphone

5.6.1 Định nghĩa

Semaphore S là biến nguyờn mà sau khi khởi tạo chỉ được truy cập qua hai thao tỏc đơn nhất là wait và signal. Hỡnh 6.1 la là định nghĩa của wait và signal. Toỏn tử wait và signal thay đổi giỏ trị semaphore được thực hiện một cỏch đơn nhất. Tức là khi một tiến trỡnh đang thay đổi giỏ trị semaphore thỡ khụng tiến trinh nào được quyền thay đổi giỏ trị semaphore. Ngoài ra, trong trường hợp wait(S), việc kiểm tra giỏ trị s (S < 0) và việc thay đổi s := s - 1 (nếu cú) phải được thực thi liờn tục khụng giỏn đoạn. Cỏch cài đặt cỏc toỏn tứ này được trỡnh bày trong mục 6.4.3. Nhưng trước tiờn ta trỡnh bày cỏch sử dụng semaphore.

Cú thể sử dụng semaphore để giải quyết vấn đề miền găng cho n tiến trỡnh, n tiến trỡnh này chia sẻ semaphore mutex (mutual exclusion) khới tạo giỏ trị 1. Tiến trỡnh Pị minh họa trong Hỡnh 6.1 Ib. "Lều Eskimo" trong vớ dụ trước được cải tiến như sau; Bảng đen sử dụng để ghi số lượng người trong lều (lều cú thể bố trớ nhiều ghế ngồi). Người muốn vào miền găng (giả sử A) bước vào lều, tăng giỏ trị ghi trong bảng đen lờn 1. Nếu giỏ trị này là 1, A cú quyền bước vào miền găng. Nếu giỏ trị này khỏc 1, A phải ngồi đợi trong lều. Sau khi thoỏt khỏi miền găng, A phải quay trở về lều, giảm giỏ trị ghi trờn bảng đen đi 1 và nếu giỏ trị này khỏc 0, thỡ người khỏc đang đợi trong lều được vào miền găng.

Ngoài ra, cũng cú thể sử dụng semaphore để giải quyết nhiều vấn đề đồng bộ húa khỏc. Giả sử hai tiến trỡnh chạy đồng thời: P1 với lệnh S1 và P2 với lệnh S2. Giả thiết rằng S2 chỉ được thực thi sau khi S1 đó thực thi xong. Cú thể giải quyết vấn đề này bằng cỏch cho Pi và P2 dựng chung semaphore synch khởi tạo bằng 0 và chốn vào cõu lệnh: {S1;signal(synch);} cho P) và cõu lệnh {wait(synch);S2 ;} cho P2. Vỡ synch khởi tạo bằng 0, P2 sẽ thực thi S2 chỉ sau khi P1 thực hiện signal(synch) sau S1.

5.6.2 Cài đặt samaphone

Với định nghĩa trờn, semaphore vẫn bị tỡnh trạng busy waiting. Để khấc phục cần định nghĩa lại toỏn tử wait và signal của semaphore. Tiến trỡnh gọi wait và thấy giỏ trị semaphore khụng dương sẽ phải chờ. Tuy nhiờn, thay vỡ thực hiện vũng lặp, tiến trỡnh phong tỏa chớnh nú. Toỏn

từ block đặt tiến trỡnh vào hàng đợi (hàng đợi này gắn với semaphore) và tiến trinh chuyển sang trạng thỏi đợi (waiting). Sau đú điều khiển được chuyển cho bộ điều phối CPU để lựa chọn tiến trỡnh khỏc thực thi. Tiến trỡnh bị phong tỏa chờ semaphore s sẽ được khởi động lại (bằng toỏn từ wakeup) khi tiến trỡnh nào đấy thi hành toỏn tử signal. Khi đú trạng thỏi tiến trỡnh này chuyển từ đợi (waiting) sang sẵn sàng (ready).

Hỡnh 37 Cài đặt semaphone

Semaphore cú thể cài đặt dưới dạng bản ghi (Hỡnh 38a), với hai thành phần: một giỏ trị nguyờn và một danh sỏch cỏc tiến trỡnh đợi. Toỏn từ signal lấy một tiến trỡnh trong danh sỏch đợi để kớch hoạt. Hỡnh 39b và c minh họa toỏn từ signal và wait. Khi gọi block, tiến trỡnh sẽ tự treo (chuyển sang trạng thỏi chờ) và chuyển sang nằm trong hàng đợi. Toỏn tử wakeup(P) khụi phục tiến trỡnh p bị phong tỏa. Hai toỏn tử này được HĐH cài đặt dưới dạng cỏc lời gọi hệ thống cơ bản. Theo định nghĩa cũ, semaphore thuộc kiểu busy waiting và giỏ trị semaphore khụng õm. Semaphore theo kiều mới cú thể nhận giỏ trị õm, khi dú độ õm xỏc định số lượng cỏc tiến trỡnh đợi trờn semaphore.

Thực tế này là do trong toỏn từ wait, chỳng ta đảo lệnh trừ lờn trước lệnh kiểm tra. Dễ dàng cỏi đặt danh sỏch cỏc tiến trỡnh đợi thụng qua trường liờn kết trong khối điều khiển tiến trỡnh (PCB). Mỗi semaphore chứa một giỏ trị nguyờn và một con trỏ trỏ tới danh sỏch PCB. Để

thờm và xúa cỏc tiến trỡnh khỏi danh sỏch và để bảo đảm điều kiện giới hạn đợi, hệ thống cú thể sử dụng hàng đợi FIFO (first-in, first-out). Khi đú, semaphore trỏ tới cả hai đầu của hàng đợi. Chỳ ý là cỏch sử dụng semaphore chớnh xỏc khụng phụ thuộc vào cỏch cài đặt danh sỏch đợi trong semaphore. Toỏn tử semaphore phải được thực hiện một cỏch toàn vẹn và đơn nhất, nghĩa là hai tiến trỡnh khụng thể cựng lỳc lại cú thể thực thi toỏn tử wait và signal trờn cựng một semaphore. Đõy là vấn đề miền găng và cú thể giải quyết theo hai cỏch sau: Trong mụi trường cú một CPU, cú thể che ngắt khi thực thi wait hoặc signal. Khi đú chỉ thị của cỏc tiến trỡnh khỏc khụng thể xen kẽ vào chỉ thị của toỏn tử. Nhưng trong mụi trường nhiều CPU, khú thực hiện việc chặn ngắt. Chỉ thị của cỏc tiến trỡnh khỏc nhau (chạy trờn cỏc CPU khỏc nhau) cú thể xen kẽ với nhau tựy ý. Nếu phần cứng khụng cú chỉ thị đặc biệt thỡ cú thể sử dụng giải phỏp phần mềm cho vấn đề miền găng, khi đú tỡnh trạng busy waiting vẫn xuất hiện với thủ tục wait và signal. Chỳng ta chỉ loại bỏ tỡnh trạng busy waiting khi chương trỡnh ứng dụng bước vào miền găng. Tỡnh trạng busy waiting bị giới hạn trong miền găng của toỏn từ wait và signal. Do độ lớn của miền này khỏ nhỏ (nếu được tối ưu sẽ khụng vượt quỏ 10 chỉ thị), nờn nếu tỡnh trạng busy waiting cú xuất hiện thỡ cũng chi trong thời gian rất ngắn.

5.7 Trao đổi thụng điệp (cơ chế IPC)

Những cơ chế đồng bộ trờn đũi hỏi cỏc tiến trỡnh cú biển dựng chung. Trong phần này, trỡnh bày cơ chế truyền thụng liờn tiến trỡnh cho phộp cỏc tiến trỡnh trao đổi dữ liệu và đồng bộ hoạt động thụng qua việc chuyển thụng điệp. Thụng điệp (message) là một khối thụng tin theo khuụn dạng nào đú (đó được thống nhất trước) được trao đổi giữa hai tiến trỡnh. Cơ chế bảo vệ bộ nhớ trong cỏc HĐH hiện đại khụng cho cỏc tiến trỡnh xõm nhập dự vụ tỡnh hay cố ý vào khụng gian nhớ của tiến trinh khỏc. Để thực hiện trao đụi thụng tin, HĐH đúng vai trũ trung chuyển thụng điệp. IPC là cơ chế cho phộp tiến trỡnh sao chộp nội dung thụng tin muốn gửi vào thụng điệp và sau đú HĐH sao chộp nội dung thụng điệp vào khụng gian địa chỉ tiến trỡnh nhận (Hỡnh 6.21).

Hỡnh 38 Cơ chế truyền thồn liờn tiến trỡnh

5.6.1 Hộp thƣ

Hỡnh 5.17 minh họa việc thụng tin được sao chộp trực tiếp sang khụng gian địa chỉ của tiến trỡnh nhận, mà phớa nhận cú thể khụng biết sự kiện này xảy ra. Cú thể trỏnh điều này bằng cỏch khụng chuyển thụng tin trừ khi phớa nhận đưa ra yờu cầu nhận tường minh. HĐH cú thể giữ tạm thụng điệp ở hộp thư trước khi sao chộp thụng tin sang khụng gian địa chỉ của tiến trỡnh nhận. Hộp thư cú thể để ở khụng gian HĐH (Hỡnh 6.22b) hoặc khụng gian địa chỉ tiến trỡnh nhận (Hỡnh 6.22a). Nếu đặt ở khụng gian người nhận, thủ tục nhận cú thể cài đặt bằng thư viện người dựng và trỡnh biờn dịch và bộ tài phải cấp phỏt bộ nhớ làm hộp thư. Tiến trỡnh

người dựng khi chạy cú thể vụ tỡnh phỏ hỏng hộp thư. Nếu hộp thư đặt trong khụng gian HĐH, phớa nhận sẽ chi nhận được thụng điệp khi tường minh gọi thủ tục nhận. Hộp thư sẽ

Một phần của tài liệu Bao cao mon hoc he dieu hanh (Trang 75)

Tải bản đầy đủ (PDF)

(131 trang)