1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng lập trình hệ điều hành chương 5 đồng bộ tiến trình

55 458 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 55
Dung lượng 2,07 MB

Nội dung

• Xét hệ thống có n tiến trình {p0, p1, … pn-1}• Mỗi tiến trình có một đoạn mã lệnh được gọi là miền tương trục critical section: o Tiến trình có thể cập nhật các dữ liệu dùng chung o Kh

Trang 1

Khoa Công Nghệ Thông Tin & Truyền Thông

Đại học Cần Thơ

Giảng viên: Hà Duy An

Trang 4

• Các tiến trình được thực thi đồng thời

Xét trường hợp: Bài toán Người sản xuất – Người tiêu thụ

(Producer – Consumer Problem) với vùng đệm có kích thước giới hạn (bounded-buffer).

Trang 5

• Dữ liệu chia sẻ:

#define BUFFER_SIZE 10typedef struct {

.} item;

Trang 6

while (true) {

/* produce an item in next produced */

while (counter == BUFFER_SIZE) ;

Trang 8

counter++ có thể được cài đặt:

register1 = counter register1 = register1 + 1 counter = register1

Counter có thể được cài đặt:

register2 = counter register2 = register2 - 1 counter = register2

• Xét sự thực thi đan xen nhau với “count = 5” là giá trị khởi tạo:

S0: producer execute register1 = counter {register1 = 5} S1: producer execute register1 = register1 + 1 {register1 = 6} S2: consumer execute register2 = counter {register2 = 5} S3: consumer execute register2 = register2 – 1 {register2 = 4} S4: producer execute counter = register1 {counter = 6 } S5: consumer execute counter = register2 {counter = 4}

Trang 9

• Nếu cả hai producer và consumer cố gắng cập nhật vùng đệm đồng thời, các phát biểu assembly có thể bị phủ lấp.

• Sự phủ lấp phụ thuộc vào cách producer và consumer được định thời.

Tình trạng đua tranh (Race Condition): là tình trạng mà vài

tiến trình cùng truy cập và thay đổi lên dữ liệu được chia sẻ và giá trị cuối cùng của dữ liệu chia sẻ phụ thuộc vào tiến trình nào hoàn thành cuối cùng.

 Để ngăn chặn tình trạng đua tranh, các tiến trình cạnh tranh phải được đồng bộ hóa.

Trang 10

Xét hệ thống có n tiến trình {p0, p1, … pn-1}

Mỗi tiến trình có một đoạn mã lệnh được gọi là miền tương

trục (critical section):

o Tiến trình có thể cập nhật các dữ liệu dùng chung

o Khi một tiến trình đang trong miền tương trục, thì không tiếntrình nào khác được phép thực thi trong miền tương trục củachúng

=> Vấn đề miền tương trục (critical-section problem): thiết kế

giao thức giải quyết vấn đề này

Trang 11

• Cấu trúc tổng quát của tiến trình Pi là:

• Mỗi tiến trình phải kiểm

tra sự hợp lệ trong phần

entry section để đi vào

miền tương trục, tiếp theo

sau khi vào miền tương

trục tiến trình sẽ thực hiện

thao tác thoát khỏi miền

tương trục exit section, và

tiếp tục thực thi phần còn

lại remainder section

Trang 12

Giải pháp cho vấn đề miền tương trục phải thỏa các yêu cầu:

1 Loại trừ hỗ tương (Mutual Exclusion) Nếu tiến trình Pi đang

thực thi trong miền tương trục, thì không có tiến trình nào khác cóthể thực thi trong miền tương trục của chúng

2 Tiến triển (Progress) Nếu không có tiến trình nào đang thực thi

trong miền tương trục và tồn tại vài tiến trình muốn được thực thitrong miền tương trục của chúng, thì việc lựa chọn một tiến trìnhđược vào miền tương trục của nó không thể bị trì hoãn mãi được

3 Chờ đợi hữu hạn (Bounded Wait) Không có tiến trình nào phải

chờ đợi vĩnh viễn để có thể đi vào miền tương trục của nó

Hai hướng tiếp cận giải quyết vấn đề phụ thuộc vào nhân HĐH:

o Non-preemptive kernel: không cho phép tiến trình bị trưng dụng khi

nó đang chạy ở chế độ nhân => vấn đề được giải quyết cho các cấu trúc

dữ liệu trong nhân

o Preemptive kernel: cho phép các tiến trình bị trưng dụng khi đang

chạy ở chế độ nhân

Trang 15

• Các biến chung:

o int turn;

khởi đầu turn = 0

o turn = i ⇒Pi có thể bước vào miền tương trục của nó

Trang 16

• Các biến chia sẻ:

o boolean flag[2];

khởi đầu flag[0] = flag[1] = false.

o flag[i] = true ⇒Pi sẵn sàng bước vào miền tương trục của nó

Trang 17

• Giải quyết được vấn đề miền tương trục (thỏa mãn cả 3 điều

kiện) cho 2 tiến trình

• Giả sử các lệnh load và store là nguyên tử (không thể bị ngắt)

• Hai tiến trình chia sẽ hai biến:

o int turn;

o Boolean flag[2]

• turn – chỉ định tiến trình nào được phép vào miền tương trục

• flag – cho biết tiến trình nào đã sẵn sàng vào miền tương trục

o flag [i] = true ⇒Pi sẵn sàng bước vào miền tương trục của nó

Trang 18

1 Loại trừ hỗ tương được đảm bảo

2 Yêu cầu tiến triển được thỏa mãn

3 Yêu cầu chờ đợi hữu hạn được đáp ứng

Trang 20

• Nhiều hệ thống cung cấp phần cứng hỗ trợ đồng bộ hóa

• Tất cả các giải pháp này dựa trên ý tưởng bảo vệ miền tương trục bằng

"khóa"

Vô hiệu hóa các ngắt: khi một tiến trình bắt đầu thực thi trong miền tương

trục thì các ngắt bị vô hiệu hóa đến khi tiến trình thoát khỏi miền tương trục

o Cho phép tiến trình người dùng có khả năng vô hiệu các ngắt => có thể tác động xấu đến sự vận hành hệ thống

o Không giải quyết được vấn đề trên hệ thống đa xử lý

Các hệ thống máy tính hiện đại cung cấp các thao tác nguyên tử (atomic

o Atomic = non-interruptible

Trang 21

• Lệnh test_and_set đọc và sửa đổi nội dung của một word một cách nguyên tử:

boolean test_and_set(boolean *target) {

Trang 23

• Tự động hoán chuyển (swap) hai biến:

int compare_and_swap(int *value,int expected,int new value){ int temp = *value;

Trang 24

• Dữ liệu chia sẻ (khởi tạo là false):

Trang 25

Dữ liệu chia sẻ (khởi tạo false): boolean lock;

else waiting[j] = false;

/* remainder section */

} while (true);

=> Thỏa tất cả các yêu cầu cho vấn đề miền tương trục

Trang 26

• Các giải pháp với test_and_set và compare_and_swap thì phức tạp và người lập trình ứng dụng thường không thể truy cập đến các lệnh này

• Người thiết kế HĐH xây dựng các công cụ phần mềm để giải quyết vấn đề này

Công cụ đơn giản nhất là Muxtex lock

Mutex lock có một biến boolean => miền tương trục có sẵn sàng hay không?

• Bảo vệ miền tương trục với 2 hàm:

o Acquire() : yêu cầu khóa trước khi vào miền tương trục

o Release() : giải phóng khóa trước khi rời khỏi miền tương trục

• Hai hàm acquire và release phải được gọi và thực thi một cách nguyên tử

o Thường được cài đặt bằng các thao tác nguyên tử được cung cấp bởi phần cứng (hardware atomic instructions) như: test_and_set hay compare_and_swap

• Muxtex lock đòi hỏi tiến trình chờ đợi bận (busy waiting) khi miền tương trục không sẵn sàng

Muxtex lock còn được gọi là spinlock

Trang 29

• Các giải pháp chờ đợi bận làm hao phí thời gian của CPU Semaphore là công cụ đồng bộ hóa không gây ra tình trạng chờ đợi bận.

• Semaphore cho phép tiến trình chờ đợi vào miền tương trục sẽ ngủ/nghẽn (sleep/blocked) và sẽ được đánh thức (wakeup) bởi một tiến trình khác.

Trang 30

Semaphore đếm – giá trị của integer của biến semaphore có một

miền giá trị không giới hạn

Semaphore nhị phân: chỉ có giá trị 0 hay 1 => giống như mutex lock

Semaphore đếm S có thể được dùng để cài đặt như là một

semaphore nhị phân

P1:

S 1 ; signal(synch);

P2:

wait(synch);

S 2 ;

Trang 31

• Định nghĩa một semaphore như là một cấu trúc gồm có:

o Một giá trị integer

o Một danh sách các tiến trình đang đợi trên nó

typedef struct { int value;

struct process *L;

} semaphore;

• Giả sử ta đã có hai thao tác được cung cấp bởi hệ điều hành như những lời gọi hệ thống cơ bản:

block() – ngưng tạm thời tiến trình gọi thao tác này.

wakeup(P) khởi động lại tiến trình P đã gọi thao tác block() trước

đó

Trang 32

• Yêu cầu: không có bất kỳ 2 tiến trình nào có thể thực thi cùng

lúc hai thao tác wait() và signal() => critical-section

problem

Cài đặt wait() và signal():

o Hệ thống đơn xử lý: vô hiệu hóa các ngắt

o Hệ thống đa xử lý:

• Dùng busy waiting (các lệnh nguyên tử hay spinlock)

• Không hoàn toàn loại bỏ được busy waiting tuy nhiên mãlệnh của wait() và signal() là ngắn => giảm bớt thờigian tiến trình phải dùng cho busy waiting

Trang 34

• Khóa chết – hai hoặc nhiều tiến trình đang chờ đợi vô hạn một

sự kiện nào đó, mà sự kiện đó chỉ có thể được tạo ra bởi một trong các tiến trình đang chờ đợi khác.

Giả sử có 2 semaphore S và Q có giá trị 1

• Sự đói CPU –bị nghẽn (block) không hạn định Một tiến trình

có thể không bao giờ được xóa khỏi hàng đợi trong semaphore.

Trang 35

1 Vùng đệm có kích thước giới hạn

2 Bộ đọc – bộ ghi

3 Các triết gia ăn tối

Trang 36

Vùng đệm có kích thước giới hạn – Bounded-Buffer

Hai tiến trình producer và consumer chia sẻ vùng đệm có kích

thước n.

• Dữ liệu chia sẻ:

o Semaphore mutex: dùng cho loại trừ hỗ tương, khởi tạo 1.

o Các Semaphore empty và full: dùng để đếm số khe trống và đầy Khởi tạo empty = n và full = 0.

Trang 39

• Một tập dữ liệu (data set) được chia sẻ giữa nhiều tiến trình thực thi đồng thời.

o Readers: tiến trình chỉ đọc, không cập nhật dữ liệu

o Writers: tiến trình thực thi cả hai thao tác đọc và ghi dữ liệu

• Vấn đề:

o Các reader có thể đọc dữ liệu chia sẽ đồng thời

o Tại một thời điểm chỉ một writer được phép truy cập dữ liệu chiasẽ

Trang 40

• Dữ liệu chia sẻ:

o Biến read_count: ghi vết số tiến trình đang đọc đối tượng Khởi tạo 0.

o Semaphore mutex: dùng cho loại trừ hỗ tương khi cập nhật biến

readcount Khởi tạo 1.

o Semaphore rw_mutex: dùng loại trừ hỗ tương cho các bộ ghi Khởi tạo rw_mutex = 1 Semaphore này cũng được dùng để

ngăn cấm các bộ ghi truy cập vào đối tượng chia sẻ khi nó đangđược đọc

Trang 43

• Năm triết gia ngồi trên bàn tròn, giữa

là bát cơm và 5 chiếc đũa như hình,

vừa ăn vừa suy nghĩ

• Khi suy nghĩ, triết gia không giao tiếp

với các triết gia khác

• Khi đói, ông ta cố gắng chọn 2 chiếc

đũa gần nhất (giữa ông ta và 2 láng

giềng) Ông ta chỉ có thể lấy được 1

chiếc đũa tại mỗi thời điểm, và không

thể lấy được đũa đang được dùng bởi

Trang 44

Philosopher i:

do {

wait(chopstick[i]) wait(chopstick[(i+1) % 5])

…// eat

signal(chopstick[i]);

signal(chopstick[(i+1) % 5]);

…// think

} while (TRUE);

Trang 45

• Giải thuật bảo đảm không có 2 láng giềng ăn cùng lúc, nhưng

có thể gây khóa chết (tình huống 5 triết gia cùng đói và mỗi người cùng lấy đũa bên trái) và đói tài nguyên.

• Các giải pháp khả dụng:

o Cho phép nhiều nhất 4 triết gia cùng ngồi trên bàn

o Cho phép một triết gia lấy đũa chỉ nếu cả hai chiếc đũa đều sẵndùng

o Dùng giải pháp bất đối xứng Ví dụ triết gia lẻ lấy đũa trái trước,rồi đến đũa phải, trong khi triết gia chẵn thao tác ngược lại

Trang 47

• Sử dụng không đúng:

o signal(mutex) … wait(mutex)

o wait(mutex) … wait(mutex)

o Thiếu wait(mutex) hoặc signal(mutex) hay cả hai

• Khóa chết và đối tài nguyên

Trang 48

Monitor là một cấu trúc của ngôn ngữ lập trình (programming language

construct), cung cấp cơ chế đồng bộ hóa ở mức ngôn ngữ cấp cao level language synchronization construct) giúp thuận tiện và hiệu quả để đồng bộ hóa các tiến trình

(high-monitor (high-monitor‐name

{ // shared variable declarations

procedure P1 (…) { …. }

.

procedure Pn (…) {……}

initialization_code (…) { … }

}

Abstract data type (ADT):

kiểu dữ liệu trừu tượng: dữ liệu

được bao bọc bởi các hàm bên

ngoài, và chỉ các hàm này được

phép truy cập đến các dữ liệu

đó => monitor type là một

ADT

Chỉ một tiến trình có thể thưc

thi bên trong monitor tại một

thời điểm => chỉ một hàm bên

trong monitor được thực thi tại

một thời điểm

Trang 49

10/29/2013 50 Chương 5: Đồng bộ hóa

Trang 50

• Condition x, y;

• Hai thao tác trên biến điều kiện:

o x.wait () – ngưng tạm thời tiến trình gọi thao tác này cho đến

khi x.signal ()

o x.signal () – phục hồi lại tiến trình đã gọi x.wait ()

Nếu không có bất kỳ tiến trình nào chờ trên biến điều kiện x hàm

signal() không gây bất cứ ảnh hưởng nào

Trang 51

10/29/2013 52 Chương 5: Đồng bộ hóa

Trang 52

Giả sử tiến trình P gọi x.signal() khi tiến trình Q đang chờ trên biến

điều kiện x, để tránh hai tiến trình thực thi cùng lúc trong monitor,một trong hai lựa chọn sau đây có thể được dùng:

1 Signal and wait: P chờ cho đến khi Q rời khỏi monitor hoặc chờ một

điều kiện khác

2 Signal and continue: Q chờ cho đến khi P rời khỏi monitor hoặc chờ

một điều kiện khác

• Lựa chọn thứ 2 được sử dụng kèm theo với điều kiện P phải lập

tức thoát ra khỏi monitor được sử dụng trong ngôn ngữ ConcurrentPascal

• Nhiều ngôn ngữ lập trình cài đặt cơ chế đồng bộ xác với ý tưởng

monitor như đã mô tả (bao gồm C# và Java)

• Một số ngôn ngữ lập trình khác (như Erlang) cung cấp các cơ chế

tương tự

Trang 53

• Dùng ngôn ngữ Pascal

được đơn giản hóa (Pidgin

Pascal) minh họa sử dụng

Monitor giải quyết bài toán

Producer-Consumer

monitor ProducerConsumer condition full, empty;

Trang 54

end end;

Ngày đăng: 14/04/2016, 15:18

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w