- Đọc/Ghi ngày, tháng, năm
HỆ ĐIỀU HÀNH NHIỀU BỘ VI XỬ LÝ
6.2.3. Hệ điều hành cho hệ thống cĩ nhiều bộ xử lý đối xứng (Symmetric multiprocessors)
multiprocessors)
Trong mơ hình này, chỉ cĩ một bản sao của hệ điều hành trong bộ nhớ, nhƣng bất kỳ CPU nào cũng cĩ khả năng sử dụng nĩ. Khi một lời gọi hệ thống đƣợc tạo ra cho một CPU nào đĩ, thì CPU này sẽ thực hiện truy xuất đến kernel của hệ điều hành và tiến hành xử lý lời gọi hệ thống đĩ. Mơ hình này đƣợc thể hiện trong hình 6-8.
Hình 6.7. Mơ hình hệ điều hành cho hệ thống đa xử lý đối xứng
Mơ hình này làm cân bằng quá trình xử lý và phân phối bộ nhớ một cách linh hoạt trong hệ thống vì nĩ chỉ hỗ trợ duy nhất một tập các bảng của hệ điều hành trên cùng một phần cứng. Ngồi ra, nĩ cịn loại bỏ đƣợc vấn đề nghẽn cổ chai trong mơ hình “chủ-tớ” vì nĩ khơng cĩ CPU nào đĩng vai trị “chủ” trong hệ thống cả. Tuy nhiên nĩ vẫn cĩ vấn đề của riêng nĩ. Nếu cĩ hai hoặc nhiều CPU đang thực thi cùng lúc các đoạn code của hệ điều hành, vấn đề nghiêm trọng sẽ xảy ra. Điều gì sẽ xảy ra nếu cĩ hai CPU chọn cùng tiến trình để thực thi và yêu cầu cùng trang nhớ rỗi? Cách đơn giản nhất để giải quyết vấn đề này là sử dụng biến mutex để cho phép khi nào thì một CPU
đƣợc đi vào miền găng để thực thi tiến trình và sử dụng trang nhớ mà nĩ cần. Khi một CPU muốn thực thi đoạn code của hệ điều hành, trƣớc tiên nĩ phải giành đƣợc mutex. Nếu mutex bị khĩa, nĩ
phải đợi. Theo cách này, bất kỳ CPU nào cũng cĩ thể thực thi code của hệ điều hành, nhƣng chỉ
tại một thời điểm chỉ cĩ một CPU đƣợc thực thi.
Tuy nhiên hiệu suất thực hiện của mơ hình này cũng khơng khá hơn mơ hình “chủ-tớ” nhiều. Giả sử rằng 10% tổng thời gian đƣợc dành cho hệ điều hành xử lý tƣơng tranh, nếu hệ thống hỗ trợ 20 CPU thì cần phải cĩ một hàng đợi CPU khá dài để các CPU lần lƣợt đƣợc phục vụ. Tuy thế, trong mơ hình này, điều này đƣợc cải thiện dễ dàng hơn. Vì rằng, nhiều phần trong một hệ điều hành là độc lập với một vài phần khác. Chẳng hạn nhƣ, sẽ chẳng cĩ vấn đề gì nếu một CPU đang thực thi việc điều phối trong khi một CPU thứ hai khác đang giải quyết một lời gọi hệ thống về tập tin và một CPU thứ ba thì lại đang xử lý vấn đề lỗi trang.
Từ nhận xét này, chúng ta thấy rõ rằng hệ thống cĩ thể đƣợc chia thành nhiều miền găng độc lập, các miền găng này khơng thực hiện bất kỳ một sự tƣơng tác nào với nhau. Mỗi miền găng đƣợc bảo vệ bởi một biến mutex của nĩ, và nhƣ vậy chỉ cĩ một CPU cĩ thể thực thi code của hệ điều
hành tại một thời điểm. Tƣơng tự nhƣ trong trƣờng hợp một bảng nào đĩ trong hệ điều hành cĩ thể đƣợc sử dụng bởi nhiều miền găng, và mỗi bảng nhƣ thế cũng cần cĩ một biến mutex của
chính nĩ để quản lý việc tƣơng tranh. Theo cách này, mỗi miền găng cĩ thể đƣợc thực thi bởi một CPU tại một thời điểm và mỗi bảng (đƣợc bảo vệ bởi miền găng) cùng cĩ thể đƣợc truy xuất chỉ bời một CPU ở một thời điểm.
Hầu hết các hệ thống cĩ nhiều bộ xử lý đều sử dụng mơ hình này. Cái khĩ trong cách tiếp cận này khơng nằm ở chỗ viết code nhƣ thế nào cho khác với một hệ điều hành thơng thƣờng trƣớc đây. Mà cái khĩ ở đây là việc chia nĩ thành nhiều miền găng để cĩ thể thực thi code của hệ điều hành
một cách đồng thời bởi nhiều CPU mà khơng bị ảnh hƣởng bởi bất kỳ một CPU nào khác. Bên cạnh đĩ, tất cả các bảng đƣợc sử dụng bởi hai hoặc nhiều miền găng phải đƣợc bảo vệ bằng một biến mutex và các đoạn code đang sử dụng bảng này cũng phải sử dụng biến muxtex một cách phù hợp.
Ngồi ra, vấn đề “khĩa chết” (deadlocks) cũng phải đƣợc quan tâm. Nếu cả hai miền găng đều cần dùng bảng A và bảng B, và một trong hai miền găng này yêu cầu bảng A trƣớc trong khi miền găng kia lại yêu cầu bảng B trƣớc. Vì vậy, trƣớc sau gì thì deadlock cũng sẽ xảy ra và khơng miền găng nào biết đƣợc lý do tại sao. Theo lý thuyết thì tất cả các bảng nên đƣợc gán các giá trị nguyên, và các miền găng cũng cần giành đƣợc các bảng theo thứ tự tăng dần. Chiến lƣợc này sẽ tránh deadlocks nhƣng nĩ địi hỏi ngƣời lập trình phải suy nghĩ rất cẩn thận để chọn ra bảng nào mà mỗi miền găng cần giành đƣợc theo đúng thứ tự. Khi code đã đƣợc phát triển sau một thời
gian thực thi, một miền găng cĩ thể cần một bảng mới mà nĩ chƣa bao giờ cần trƣớc đây. Nếu một lập trình viên chƣa cĩ kinh nghiệm và chƣa hiều rỏ về họat động logic của hệ thống thì sẽ dễ dàng thực hiện việc chọn ra một mutex cho bảng mà miền găng cần và sau đĩ giải phịng nĩ đi khi khơng cịn cần đến nữa. Điều này dễ dẩn đến deadlocks. Vì vậy, việc sử dụng biến mutex đã
khơng dễ thì việc giữ nĩ làm việc đúng trong suốt quá trình họat động của hệ thống là điều cực hơn đối với các lập trình viên.