Professional Documents
Culture Documents
Student OS 04
Student OS 04
Student OS 04
Operating Systems
Những tiến trình cùng tồn tại được gọi là tiến trình đồng thời
(concurrent process) hay còn được gọi là tiến trình tương
tranh.
Quản lý tiến trình đồng thời bao gồm nhiều vấn đề liên quan
tới liên lạc giữa các tiến trình, cạnh tranh và chia sẻ tài
nguyên, phối hợp và đồng bộ hóa hoạt động các tiến trình,
vấn đề bế tắc (deadlock) và đói tài nguyên (starvation).
Phần này sẽ tập trung vào đồng bộ hóa tiến trình.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Trong hệ thống với một CPU, thời gian CPU được phân phối
cho các tiến trình đang tồn tại trong hệ thống, tại mỗi thời
điểm, chỉ một tiến trình duy nhất được thực hiện.
Đối với hệ thống nhiều CPU, một số tiến trình có thể thực
hiện song song với nhau.
Mặc dù vậy, trong cả hai trường hợp, vấn đề quản lý tương
tranh đều được đặt ra tương tự nhau.
Lý do là ngay cả khi chỉ có một CPU, do thời gian thực hiện
và hành vi của từng tiến trình không thể dự đoán trước,
cũng như do đặc điểm điều độ và khả năng xảy ra ngắt trong
hệ thống, hoạt động của tiến trình có thể xen kẽ theo những
cách không thể xác định trước.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Tiến trình có thể có quan hệ hợp tác với nhau. Một trong các
phương pháp trao đổi thông tin giữa các tiến trình hợp tác là
chia sẻ với nhau vùng bộ nhớ dùng chung (các biến toàn
cục), hay các file. Việc các tiến trình đồng thời truy cập dữ
liệu dùng chung làm nảy sinh vấn đề đồng bộ hóa, đòi hỏi
thao tác truy cập phải tính tới tính nhất quán của dữ liệu.
Trước hết, việc cập nhật dữ liệu dùng chung đòi hỏi đảm bảo
loại trừ tương hỗ. Ngoài ra cũng xuất hiện tình trạng bế tắc
và đói tương tự như đã nhắc tới ở trên.
Bên cạnh đó, xuất hiện yêu cầu đảm bảo tính nhất quán của
dữ liệu.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Bên cạnh đó, xuất hiện yêu cầu đảm bảo tính nhất quán của
dữ liệu.
Ví dụ 1: hai tiến trình P1 và P2 cùng cập nhật hai biến
nguyên x và y như sau:
Khởi đầu: x = y =2
P1:
x = x +1
y = y +1
P2:
x=x*2
y=y*2
Theo logic thông thường, sau khi thực hiện các biến đổi trên,
ta phải có x = y.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Giả sử tình huống P1 và P2 được thực hiện đồng thời. Do
kết quả điều độ, thứ tự thực hiện P1 và P2 diễn ra như sau:
P1:
x=x+1
P2:
x=x*2
y=y*2
P1: Kết quả ta có x = 6, y = 5 và như vậy x ≠
y=y+1 y. Tính nhất quán của dữ liệu bị phá vỡ.
Kết quả thực hiện trong những trường hợp như vậy phụ
thuộc vào thứ tự thay đổi giá trị hai biến x và y và được gọi
là điều kiện chạy đua.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Hình minh họa dưới đây cho thấy các kết quả không nhất
quán có thể được tạo ra như thế nào nếu nhiều quy trình thực
thi đồng thời mà không có bất kỳ đồng bộ hóa nào.
• Hai tiến trình P1 và P2 đang
thực hiện đồng thời.
• Cả hai tiến trình đều chia sẻ
một biến chung có tên là
“count” có giá trị ban đầu = 5.
• Tiến trình P1 cố gắng tăng giá
Khi các tiến trình này thực hiện trị của số đếm.
đồng thời mà không đồng bộ hóa, • Tiến trình P2 cố gắng giảm
các kết quả khác nhau có thể được giá trị của số đếm.
tạo ra.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Các vấn đề đối với tiến trình đồng thời
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trong assembly language, các lệnh của hai tiến trình có thể
được viết dưới dạng:
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trường hợp 1: Thứ tự thực hiện của các lệnh có thể là:
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trường hợp 2: Thứ tự thực hiện của các lệnh có thể là:
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trường hợp 3: Thứ tự thực hiện của các lệnh có thể là:
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trường hợp 4: Thứ tự thực hiện của các lệnh có thể là:
Tiến trình hợp tác với nhau thông qua tài nguyên chung
Điều kiện chạy đua (race condition) – Ví dụ 2:
Trường hợp 5: Thứ tự thực hiện của các lệnh có thể là:
Các tiến trình hợp tác có thể trao đổi thông tin trực tiếp với
nhau bằng cách gửi thông điệp (message passing). Cơ chế
liên lạc được hỗ trợ bởi thư viện của ngôn ngữ lập trình hoặc
bản thân hệ điều hành.
Trong trường hợp trao đổi thông điệp, tiến trình không chia
sẻ hoặc cạnh tranh tài nguyên và vì vậy không có yêu cầu
loại trừ tương hỗ. Tuy nhiên có thể xuất hiện bế tắc và đói.
Bế tắc có thể xuất hiện, chẳng hạn khi hai tiến trình đều chờ
thông điệp từ tiến trình kia trước khi có thể thực hiện tiếp.
Tình trạng đói có thể xuất hiện khi một tiến trình phải chờ
đợi quá lâu những tiến trình khác trong khi những tiến trình
kia bận trao đổi thông điệp với nhau.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Yêu cầu với giải pháp cho đoạn nguy hiểm
Yêu cầu quan trọng khi đồng bộ hóa tiến trình là giải quyết
vấn đề đoạn nguy hiểm (critical section) và loại trừ tương
hỗ. Giải pháp cho vấn đề đoạn nguy hiểm cần thỏa mãn
những yêu cầu sau:
Loại trừ tương hỗ: nếu nhiều tiến trình có đoạn nguy hiểm
đối với cùng một tài nguyên thì tại mỗi thời điểm, chỉ một
tiến trình được ở trong đoạn nguy hiểm.
Tiến triển: một tiến trình đang thực hiện ở ngoài đoạn nguy
hiểm không được phép ngăn cản các tiến trình khác vào
đoạn nguy hiểm của mình. Chẳng hạn, nếu một tiến trình bị
treo ở ngoài đoạn nguy hiểm thì điều đó không được phép
ảnh hưởng tới tiến trình khác.
Chờ đợi có giới hạn: nếu tiến trình có nhu cầu vào đoạn
nguy hiểm thì tiến trình đó phải được vào sau một khoảng
thời gian hữu hạn nào đó. Điều này có nghĩa là không được
phép xảy ra bế tắc hoặc tình trạng bị đói đối với tiến trình.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải thuật Peterson
Giải thuật Peterson là một giải thuật được sử dụng để giải
quyết vấn đề đồng bộ hóa trong lập trình đa luồng. Giải thuật
này được phát triển bởi Martin Peterson vào năm 1981.
Vấn đề đồng bộ hóa là khi nhiều tiến trình hoặc dòng cùng
truy cập vào một tài nguyên chung, gây ra xung đột và dẫn
đến lỗi. Giải thuật Peterson được sử dụng để tránh tình trạng
deadlock trong khi đảm bảo đồng bộ hóa truy cập vào tài
nguyên chung.
Giải thuật Peterson sử dụng hai biến flag và turn để đảm bảo
việc truy cập đồng bộ vào tài nguyên chung. Biến flag được
sử dụng để chỉ định xem tiến trình đang muốn truy cập tài
nguyên chung hay không. Biến turn được sử dụng để xác
định rằng tiến trình đang chờ đợi truy cập tài nguyên chung.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải thuật Peterson
Khi một tiến trình muốn truy cập tài nguyên chung, nó đặt
flag của mình và đặt turn cho tiến trình khác. Nếu tiến trình
khác muốn truy cập tài nguyên chung cũng đặt flag, nó phải
chờ đợi cho đến khi flag của tiến trình khác được đặt lại và
lượt của nó được đến. Khi tiến trình hoàn thành việc truy cập
tài nguyên chung, nó sẽ đặt lại flag của mình và cho phép
tiến trình khác tiếp tục thực hiện.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải thuật Peterson
int turn;
boolean flag[2] = {false, false};
// Tiến trình A
flag[A] = true;
turn = B;
while (flag[B] && turn == B);
// Tiến hành tăng giá trị của biến toàn cục
...
// Hoàn thành việc truy cập tài nguyên chung
flag[A] = false;
// Tiến trình B
flag[B] = true;
turn = A;
while (flag[A] && turn == A);
// Tiến hành tăng giá trị của biến toàn cục
...
// Hoàn thành việc truy cập tài nguyên chung
flag[B] = false;
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải thuật Peterson
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải thuật Peterson
Việc sử dụng giải thuật Peterson trên thực tế tương đối phức
tạp.
Ngoài ra nhóm giải pháp này đòi hỏi tiến trình đang yêu cầu
vào đoạn nguy hiểm phải nằm trong trạng thái chờ đợi tích
cực (busy waiting). Chờ đợi tích cực là tình trạng chờ đợi
trong đó tiến trình vẫn phải sử dụng CPU để kiểm tra xem có
thể vào đoạn nguy hiểm hay chưa.
Đối với giải thuật Peterson, tiến trình phải lặp đi lặp lại thao
tác kiểm tra trong vòng while trước khi vào được đoạn nguy
hiểm, và do vậy gây lãng phí thời gian CPU.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Cấm các ngắt
Trong trường hợp máy tính chỉ có một CPU, tại mỗi thời
điểm chỉ một tiến trình được thực hiện. Tiến trình đang có
CPU sẽ thực hiện cho đến khi tiến trình đó gọi dịch vụ hệ
điều hành hoặc bị ngắt. Như vậy, đề giải quyết vấn đề đoạn
nguy hiểm ta chỉ cần cấm không để xảy ra ngắt trong thời
gian tiến trình đang ở trong đoạn nguy hiểm để truy cập tài
nguyên.
Mặc dù đơn giản, việc cấm ngắt làm giảm tính mềm dẻo của
hệ điều hành, có thể ảnh hưởng tới khả năng đáp ứng các sự
kiện cần ngắt. Ngoài ra, giải pháp cấm ngắt không thể sử
dụng đối với máy tính nhiều CPU. Trong khi cấm ngắt ở
CPU này, tiến trình vẫn có thể được cấp CPU khác để vào
đoạn nguy hiểm. Việc cấm ngắt đồng thời trên tất cả CPU đòi
hỏi nhiều thời gian để gửi thông điệp tới tất cả CPU, làm
chậm việc vào đoạn nguy hiểm.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Nguyên tắc chung của giải pháp này là hai thao tác kiểm tra
giá trị và thay đổi giá trị cho một biến (một ô nhớ), hoặc các
thao tác so sánh và hoán đổi giá trị hai biến, được thực hiện
trong cùng một lệnh máy và do vậy sẽ đảm bảo được thực
hiện cùng nhau mà không bị xen vào giữa. Đơn vị thực hiện
không bị xen vào giữa như vậy được gọi là thao tác nguyên
tử (atomic). Ta sẽ gọi lệnh như vậy là lệnh “kiểm tra và xác
lập” Test_and_Set.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Ta có thể sử dụng lệnh Test_and_Set để giải quyết vấn đề
đoạn nguy hiểm đồng thời cho n tiến trình ký hiệu P(1) đến
P(n) như sau:
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Có thể dễ dàng kiềm tra điều kiện loại trừ tương hỗ được
bảo đảm khi sử dụng giải pháp với Test_and_Set như trên.
Thật vậy, tiến trình chỉ có thể vào được đoạn giới hạn nếu
lock=false. Do việc kiểm tra giá trị lock và thay đổi
lock=true được đảm bảo thực hiện cùng nhau nên tiến trình
đầu tiên kiểm tra thấy lock=false sẽ đảm bảo thay đổi lock
thành true trước khi tiến trình khác kiểm tra được biến này.
Điều này đảm bảo duy nhất một tiến trình vào được đoạn
nguy hiểm.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Ưu điểm:
- Việc sử dụng tương đối đơn giản và trực quan.
- Giải pháp có thể dùng để đồng bộ nhiều tiến trình, tất cả
đề sử dụng chung lệnh Test_and_Set trên một biến chung
gắn với một tài nguyên chung.
- Có thể sử dụng cho trường hợp đa xử lý với nhiều CPU
nhưng có bộ nhớ chung. Cần lưu ý là trong trường hợp
này, mặc dù hai CPU có thể cùng thực hiện lệnh
Test_and_Set nhưng do hai lệnh cùng truy cập một biến
chung nên việc thực hiện vẫn diễn ra tuần tự.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Nhược điểm:
- Chờ đợi tích cực. Tiến trình muốn vào đoạn nguy hiểm
phải liên tục gọi lệnh Test_and_Set trong vòng lặp while
cho tới khi nhận được kết quả lock=false.
- Việc sử dụng lệnh Test_and_Set có thể gây đói. Trong
trường hợp có nhiều tiến trình cùng chờ để vào đoạn giới
hạn, việc lựa chọn tiến trình tiếp theo không theo quy
luật nào và có thể làm cho một số tiến trình không bao
giờ vào được đoạn giới hạn.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Giải pháp phần cứng
Sử dụng lệnh máy đặc biệt
Nhược điểm:
- Chờ đợi tích cực. Tiến trình muốn vào đoạn nguy hiểm
phải liên tục gọi lệnh Test_and_Set trong vòng lặp while
cho tới khi nhận được kết quả lock=false.
- Việc sử dụng lệnh Test_and_Set có thể gây đói. Trong
trường hợp có nhiều tiến trình cùng chờ để vào đoạn giới
hạn, việc lựa chọn tiến trình tiếp theo không theo quy
luật nào và có thể làm cho một số tiến trình không bao
giờ vào được đoạn giới hạn.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Cờ hiệu (semaphore)
Cờ hiệu S là một biến nguyên được khởi tạo một giá trị ban
đầu nào đó, bằng khả năng phục vụ đồng thời của tài
nguyên. Trừ thao tác khởi tạo, giá trị của cờ hiệu S chỉ có thể
thay đổi nhờ gọi hai thao tác là Wait và Signal.
Hai thao tác này có ý nghĩa như sau:
- Wait(S): Giảm S đi một đơn vị. Nếu giá trị của S âm sau
khi giảm thì tiến trình gọi thao tác P(S) sẽ bị phong tỏa
(blocked). Nếu giá trị của S không âm, tiến trình sẽ được
thực hiện tiếp.
- Signal(S): Tăng S lên một đơn vị. Nếu giá trị S nhỏ hơn
hoặc bằng 0 sau khi tăng thì một trong các tiến trình đang
bị phong tỏa (nếu có) sẽ được giải phóng và có thể thực
hiện tiếp.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Cờ hiệu (semaphore)
Xây dựng cờ hiệu
Cờ hiệu có thể được xây dựng dưới dạng một cấu trúc trên
ngôn ngữ C với hai thao tác Wait và Signal như sau:
Mỗi cờ hiệu có một giá trị
và một danh sách queue
chứa tiến trình bị phong
tỏa. Thao tác block()
trong Wait phong tỏa tiến
trình gọi Wait và thao tác
wakeup() trong Signal
khôi phục tiến trình phong
tỏa về trạng thái sẵn sàng.
Hai thao tác block và
wakeup được thực hiện
nhờ những lời gọi hệ
thống của hệ điều hành.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Cờ hiệu (semaphore)
Cách sử dụng cờ hiệu
Cờ hiệu được tiến trình sử dụng để gửi tín hiệu trước khi vào đoạn nguy
hiểm và sau khi ra khỏi đoạn nguy hiểm. ðầu tiên, cờ hiệu được khởi tạo
một giá trị dương hoặc bằng không. Mỗi cờ hiệu với giá trị đầu dương
thường dùng để kiểm soát việc truy cập một tài nguyên với khả năng
phục vụ đồng thời một số lượng hữu hạn tiến trình. Ví dụ, tại mỗi thời
điểm tài nguyên như máy in chỉ cho phép một tiến trình ghi thông tin, và
cờ hiệu dùng cho máy in được khởi tạo bằng 1.
Khi tiến trình cần truy cập tài nguyên, tiến trình thực hiện thao tác Wait
của cờ hiệu tương ứng. Nếu giá trị cờ hiệu âm sau khi giảm có nghĩa là
tài nguyên được sử dụng hết khả năng và tại thời điểm đó không phục vụ
thêm được nữa. Do vậy, tiến trình thực hiện Wait sẽ bị phong tỏa cho đến
khi tài nguyên được giải phóng. Nếu tiến trình khác thực hiện Wait trên
cờ hiệu, giá trị cờ hiệu sẽ giảm tiếp. Giá trị tuyệt đối của cờ hiệu âm
tương ứng với số tiến trình bị phong tỏa.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Cờ hiệu (semaphore)
Cách sử dụng cờ hiệu
Sau khi dùng xong tài nguyên, tiến trình thực hiện thao tác
Signal trên cùng cờ hiệu. Thao tác này tăng giá trị cờ hiệu và
cho phép một tiến trình đang phong tỏa được thực hiện tiếp.
Nhờ việc phong tỏa các tiến trình chưa được vào đoạn nguy
hiểm, việc sử dụng cờ hiệu tránh cho tiến trình không phải
chờ đợi tích cực và do vậy tiết kiệm được thời gian sử dụng
CPU.
ĐỒNG BỘ HÓA TIẾN TRÌNH ĐỒNG THỜI
Một số bài toán đồng bộ
Bài toán triết gia ăn cơm