Mời các bạn cùng tham khảo Bài giảng Quản trị kinh doanh - Bài 2: Quản lý tiến trình để nắm chi tiết các nội dung về khái niệm tiến trình; đồng bộ và giải pháp giải quyết tranh chấp; tắc nghẽn.
Trang 1Nội dung
Khái niệm tiến trình
Đồng bộ và giải pháp giải quyết tranh chấp
Tắc nghẽn
Trình bày được khái niệm về tiến trình,
các trạng thái của tiến trình và quá trình
biến đổi trạng thái đó
Trình bày được các khái niệm về luồng,
đồng bộ và giải quyết tranh chấp
Trình bày được những vấn đề liên quan
đến Deadlock
9 tiết
BÀI 2: QUẢN LÝ TIẾN TRÌNH
Trang 2Bài 2: Quản lý tiến trình
TÌNH HUỐNG DẪN NHẬP
Tình huống
Task Manager là một tiện ích giúp chúng ta quản lý các tiến
trình trong máy tính Vậy các tiến trình đó hoạt động như
thế nào?
Câu hỏi
Đôi lúc ta gặp tình huống máy bị treo Tại sao lại có hiện tượng đó? Có thể ngăn chặn và khôi phục nếu hiện tượng đó xảy ra không?
Trang 32.1 Khái niệm tiến trình (Process)
Trong bài này chúng ta sẽ xem xét khái niệm tiến trình, một khái niệm quan trọng nhất
để hình dung về công việc của máy tính ngày nay
Chúng ta sẽ tìm hiểu khái niệm về các trạng thái (rời rạc) của tiến trình và cũng như cách mà tiến trình chuyển từ trạng thái này sang trạng thái khác cùng với các thao tác
cơ bản trên tiến trình
Khái niệm tiến trình lần đầu tiên được các kỹ sư thiết kế hệ thống MULTICS vào những năm 60 Trong thời kỳ đầu tiên, tiến trình được hiểu trong nhiều trường hợp đồng nghĩa như là chương trình, bài toán (Task) hay là đối tượng được bộ xử lý phục vụ,
Người ta thường dùng định nghĩa tiến trình như là chương trình trong lúc chạy
Đại diện cho một tiến trình trong hệ điều hành là khối điều khiển tiến trình (PCB) PCB là một cấu trúc dữ liệu chứa những thông tin quan trọng về tiến trình và có thể khác nhau trong các hệ thống khác nhau, trong đó thường có:
Trạng thái hiện tại của tiến trình
ID (Identifier) duy nhất cho tiến trình
Độ ưu tiên (Priority) của tiến trình
Thông tin về bộ nhớ
Thông tin về các tài nguyên tiến trình đang sử dụng
Vùng để cho các thanh ghi
PCB là đối tượng quan trọng, nhờ nó hệ điều hành có thể có được toàn bộ thông tin cơ bản nhất về một tiến trình Khi hệ điều hành chuyển (Switch) bộ xử lý từ đang phục
vụ tiến trình này sang phục vụ tiến trình khác, nó dùng vùng cho các thanh ghi trong PCB lưu thông tin giá trị các thanh ghi của hệ thống để có thể tiếp tục thực hiện tiến trình mỗi khi tiến trình đến lượt được sử dụng bộ xử lý
Tóm lại, PCB là đối tượng chính đại diện cho tiến trình đối với hệ điều hành Vì hệ điều hành phải có khả năng thực hiện các thao tác với các PCB khác nhau một cách nhanh chóng, trong nhiều hệ thống có những thanh ghi đặc biệt luôn chỉ tới PCB của tiến trình đang chạy (Running Process) và cũng có những lệnh cài đặt ngay trong phần cứng để đảm bảo nhanh chóng ghi thông tin trạng thái vào PCB và tiếp theo là nhanh chóng đọc các thông tin đó
Các thao tác với tiến trình:
Hệ thống điều khiển tiến trình cần có khả năng thực hiện các thao tác với tiến trình, trong đó có:
Tạo tiến trình (Create)
Huỷ tiến trình (Free, Destroy)
Thay đổi độ ưu tiên (Priority)
Dừng (Block) tiến trình
Kích hoạt (Waikup) tiến trình
Thực hiện (Dispatch) tiến trình
Trang 4Bài 2: Quản lý tiến trình
Tiến trình tạo một tiến trình gồm nhiều thao tác nhỏ:
Gán tên cho tiến trình
Đưa tên tiến trình vào danh sách các tiến trình
của hệ thống
Xác định mức ưu tiên (Priority) ban đầu cho
tiến trình
Tạo, nạp thông tin PCB
Phân chia tài nguyên khởi đầu cho tiến trình
Tạo mới tiến trình:
Một tiến trình có thể tạo ra tiến trình mới Tiến trình đầu tiên là tiến trình cha (Parent Process) còn tiến trình mới được tạo ra là tiến trình con (Child Process) Để tạo tiến trình mới chỉ cần một tiến trình đã có Tức là mỗi tiến trình con chỉ có một tiến trình cha còn một tiến trình cha có thể có nhiều tiến trình con Các quan hệ đó tạo ra kiến trúc tiến trình
Xoá tiến trình:
Xoá một tiến trình là loại bỏ nó khỏi hệ thống Khi đó các tài nguyên được phân chia cho tiến trình sẽ được giải phóng, trả lại cho hệ điều hành, tên của tiến trình được xoá khỏi tất cả các danh sách của hệ thống, còn PCB cũng được giải phóng
Dừng/ hoãn tiến trình:
Một tiến trình bị hoãn–dừng (Suspended Process) là tiến trình không tiếp tục được thực hiện đến khi có một tiến trình khác kích hoạt nó Tạm dừng (Suspending) là một thao tác quan trọng được sử dụng trong nhiều hệ thống với các cách cài đặt, thực hiện khác nhau Tạm dừng thường chỉ diễn ra trong khoảng thời gian ngắn
Ví dụ: hệ điều hành phải tạm dừng một số tiến trình (không phải luôn là tất cả) trong thời gian ngắn khi hệ thống quá tải,…
Trong trường hợp tiến trình bị dừng trong thời gian dài hơn thì các tài nguyên của nó phải được giải phóng trả lại cho hệ điều hành Việc một loại tài nguyên có cần giải phóng hay không còn phụ thuộc vào kiểu của nó
Ví dụ: bộ nhớ cần được giải phóng ngay, còn thiết bị vào ra có thể vẫn thuộc quyền sử dụng tiến trình trong trường hợp tiến trình bị hoãn–dừng trong thời gian ngắn còn sẽ được giải phóng khi thời gian Suspend dài hay không xác định
Tiến trình kích hoạt (Activate) là thao tác chuẩn bị để tiến trình có thể tiếp tục thực hiện từ đúng trạng thái mà nó bị dừng trước đó
Quá trình huỷ bỏ một tiến trình sẽ khá phức tạp nếu nó là tiến trình cha Trong một số
hệ thống thì các tiến trình con sẽ tự động bị huỷ bỏ theo, còn trong một số hệ thống khác thì tiến trình con vẫn tồn tại (độc lập với tiến trình cha)
Sự thay đổi độ ưu tiên của một tiến trình thường đơn giản là thay đổi giá trị ưu tiên trong PCB bởi hệ điều hành
Trong thời gian tồn tại của mình, tiến trình tồn tại trong các trang thái tách biệt (rời rạc)
Sự đổi từ trạng thái này sang trạng thái khác có thể xảy ra bởi các sự kiện khác nhau
A
Trang 5Ta nói rằng tiến trình ở trạng thái hoạt động (Running State) nếu nó đang được bộ xử
lý phục vụ Còn nếu tiến trình đã sẵn sàng để được bộ xử lý phục vụ nhưng đang chờ đến lượt thì tiến trình ở trạng thái sẵn sàng (Ready State) Nói rằng tiến trình ở trạng thái bị cản, chặn (Blocked State) nếu như nó đang chờ một sự kiện nào đó (ví dụ kết thúc tác vụ vào/ra) để có thể tiếp tục hoạt động Ngoài 3 trạng thái nói trên còn một số trạng thái khác nhưng tạm thời chúng ta chỉ xem xét quan hệ giữa 3 trạng thái trên
Để đơn giản chúng ta xem xét trường hợp máy tính chỉ có một bộ xử lý Trong hệ thống một bộ xử lý, tại một thời điểm chỉ có thể có một tiến trình được thực hiện, còn một số tiến trình nằm trong trạng thái sẵn sàng (Ready) và một số khác trong trạng thái bị chặn (Blocked) Do đó chúng ta có thể lập một danh sách chứa các tiến trình ở trạng thái Ready và một danh sách các tiến trình bị khóa Mỗi tiến trình sẵn sàng nằm trong danh sách thứ nhất sẽ có mức độ ưu tiên riêng (Priority) của mình– tức là các tiến trình đó được sắp xếp theo thứ tự và tiến trình nằm ở đầu danh sách sẽ là tiến trình có độ ưu tiên cao nhất và sẽ được bộ xử lý thực hiện tiếp theo (có nhiều tiêu chuẩn để gán độ ưu tiên và thay đổi độ ưu tiên) Còn danh sách các Blocked Process nói chung không có thứ tự vì Blocked Process sẽ được giải phóng (Unblock) bởi các
sự kiện mà nó đang chờ
Khi có một chương trình (Task) bắt đầu được thực hiện, hệ thống sinh ra một tiến trình tương ứng và tiến trình đó được đưa vào danh sách các tiến trình sẵn sàng, đơn giản nhất là đưa vào cuối danh sách – tức là có mức ưu tiên thấp nhất Tiến trình này
sẽ dịch chuyển dần lên phía đầu danh sách bởi vì các tiến trình trước nó dần dần được
bộ xử lý phục vụ Khi tiến trình nằm ở đầu danh sách và bộ xử lý được giải phóng thì tiến trình này được bộ xử lý phục vụ và lúc đó xảy ra sự thay đổi trạng thái của tiến trình – chuyển từ trạng thái Ready sang Running Việc trao quyền sử dụng bộ xử lý cho tiến trình đầu tiên trong danh sách các tiến trình sẵn sàng gọi là tiến trình dispatching, điều đó được thực hiện bởi module chương trình nằm trong OS gọi là Dispatcher
tiến trình đổi trạng thái đó có thể biểu diễn bằng ký hiệu:
dispatch(Process name): Ready Running Tiến trình đang sử dụng bộ xử lý được gọi là tiến trình đang được thực hiện
Để ngăn chặn trường hợp vô tình hoặc cố ý độc
quyền chiếm tài nguyên hệ thống của tiến trình, hệ
điều hành sinh ra một ngắt cứng đặc biệt ngắt thời
gian (Timer Interrupt) nhằm xác định khoảng thời
gian lớn nhất mà một tiến trình được sử dụng bộ
xử lý liên tục Nếu như sau khoảng thời gian đó,
tiến trình không tự giải phóng bộ xử lý thì hệ thống
sẽ sinh ngắt, theo đó quyền điều khiển được
chuyển lại cho hệ điều hành Lúc đó hệ điều hành
sẽ chuyển tiến trình đang được thực hiện từ trạng thái Running về trạng thái Ready, đưa nó vào danh sách các tiến trình sẵn sàng, sau đó đưa tiến trình đầu tiên trong danh sách (tiến trình có mức ưu tiên cao nhất) vào thực hiện (Running State) Các sự biến đổi này có thể biểu diễn bằng hai thao tác:
Running
Blocked Ready
Waik up Over time
Trang 6Bài 2: Quản lý tiến trình
interval gone (Process name): Running Ready dispatch (Process name): Ready Running Nếu như một tiến trình đang sử dụng bộ xử lý (Running State) trong quá trình hoạt động của mình thực hiện tác vụ vào/ra (I/O) thì nó sẽ tự mình giải phóng bộ xử lý (tự mình chuyển vào trạng thái Blocked để chờ tác vụ vào/ra kết thúc) Sự chuyển trạng thái này có thể biểu diễn:
blocking (Process name): Running Blocked Còn một tiến trình thay đổi trạng thái cuối cùng, đó là khi kết thúc tác vụ vào/ra (hay nói chung xảy ra một sự kiện mà tiến trình bị khóa đang chờ) lúc đó tiến trình chuyển
từ trạng thái Blocked sang trạng thái Ready – sẵn sàng để thực hiện tiếp Tiến trình này có thể biểu diễn:
waikup(Process name): Blocked ReadyVới 3 trạng thái cơ bản trên, chúng ta có 4 khả năng chuyển trạng thái của một tiến trình đó là:
Dispatch (Process name): Ready Running interval gone(Process name): Running Ready blocking (Process name): Running Blocked waikup (Process name): Blocked Ready
Chú ý:
Trong 4 khả năng trên, chỉ có khả năng thứ 3 là có thể sinh ra bởi chính chương trình người sử dụng, còn lại các khả năng khác đều do các đối tượng khác ở bên ngoài tiến trình gây ra
Tạm dừng và kích hoạt (Suspending and Activating):
Chúng ta đã biết các khái niệm tạm dừng và kích hoạt Các thao tác này khá quan trọng do các lý do:
Nếu hệ thống hoạt động không
ổn định có dấu hiệu trục trặc thì các tiến trình đang diễn ra cần tạm dừng để lại được kích hoạt sau khi sửa lỗi
Người sử dụng (lập trình viên)
có thể cần tạm dừng (không phải huỷ bỏ) tiến trình để kiểm tra kết quả trung gian xem chương trình
có hoạt động đúng hay không
Một số tiến trình có thể bị tạm dừng trong khoảng thời gian ngắn khi hệ thống quá tải và sau đó lại được kích hoạt khi có đủ tài nguyên (hệ thống trở về trạng thái bình thường)
So với mục trước, ta có thêm hai trạng thái ứng với các thao tác tạm dừng và kích hoạt Tác nhân dừng có thể là chính bản thân tiến trình hay là tiến trình khác
Trong hệ có một bộ xử lý thì tiến trình chỉ có thể dừng chính bản thân nó vì không có tiến trình khác nào đang chạy đồng thời với nó Còn trong hệ điều hành có nhiều bộ xử
lý thì một tiến trình có thể bị dừng bởi tiến trình khác đang chạy trên bộ xử lý khác
Running
Blocked Ready Dispatch
Waik up Over time
Ready suspend
Blocked suspend
Event Terminated
Suspend Activate
Suspend
Suspend
Activate Event Terminated
ACTIVE STATE SUSPENDED STATE
Trang 7Một tiến trình ở trạng thái Ready chỉ có thể bị dừng bởi tiến trình khác, lúc đó xảy ra
sự chuyển trạng thái:
Suspend (Process name): Ready Suspended–ReadyTiến trình đang ở trạng thái Suspended–Ready có thể chuyển về trạng thái Ready bởi tiến trình khác; tiến trình chuyển trạng thái đó có thể biểu diễn bởi:
Activate (Process name): Suspend–Ready ReadyTiến trình đang ở trạng thái Blocked có thể chuyển sang trạng thái Suspend bởi một tiến trình khác, khi đó diễn ra sự đổi trạng thái:
Suspend (Process name): Blocked Suspend–Blocked
Và ngược lại, tiến trình ở trạng thái Suspended Blocked có thể được kích hoạt bởi một tiến trình khác
Activate (Process name): Suspended–Blocked Blocked Chúng ta có thể đặt vấn đề tại sao không thay vì tạm dừng một tiến trình ở trạng thái Blocked, ta vẫn chờ đến khi có sự kiện (kết thúc I/O) mà tiến trình đợi xảy ra để tiến trình chuyển về trạng thái Ready Tuy nhiên tác vụ I/O hay sự kiện tiến trình chờ có thể không xảy ra hay không biết khi nào mới xảy ra
Như thế, các nhà thiết kế cần phải chọn lựa: tạm dừng một Blocked Process (đưa về trạng thái Suspended–Blocked) hoặc phải sinh ra cơ chế cho phép đưa tiến trình từ trạng thái Blocked sang trạng thái Ready và sau đó chuyển thành trạng thái Suspended–Ready khi kết thúc I/O hay diễn ra sự kiện tiến trình đang chờ
Mặt khác thao tác tạm dừng thường có mức ưu tiên cao và cần thực hiện ngay, do đó phần lớn các hệ thống sử dụng cách thứ nhất Khi sự kiện tiến trình đang chờ xảy ra (nếu như nó xảy ra), trạng thái của tiến trình sẽ chuyển từ Suspended – Blocked sang trạng thái Suspended – Ready:
Incommingevent (Process name): Suspended–Blocked Suspended–Ready
Khái niệm:
Luồng là một dòng điều khiển trong phạm vi một tiến trình Tiến trình đa luồng gồm nhiều dòng điều khiển khác nhau trong cùng không gian địa chỉ
Một luồng thường được gọi là tiến trình nhẹ (Lightweight Process–LWP), là một đơn
vị cơ bản của việc sử dụng CPU; nó hình thành gồm:
Một định danh luồng (Thread ID)
Một tiến trình truyền thống (hay tiến trình nặng) có một luồng điều khiển đơn
Nếu tiến trình có nhiều luồng điều khiển, nó có thể thực hiện nhiều hơn một tác vụ tại một thời điểm
Tại sao đa luồng?
Trong nhiều trường hợp, một ứng dụng có thể được yêu cầu thực hiện nhiều tác vụ
Trang 8Bài 2: Quản lý tiến trình
Ví dụ: Một máy chủ Web thể phải phục vụ hàng trăm trình duyệt truy xuất đồng thời Nếu máy chủ Web chạy như một tiến trình đơn luồng truyền thống thì nó sẽ có thể chỉ phục vụ một trình khách tại cùng thời điểm Dẫn đến thời gian mà trình khách phải chờ yêu cầu của nó được phục vụ là rất lớn
Giải pháp thứ nhất là sử dụng đa tiến trình, có một
tiến trình phục vụ chạy như một tiến trình đơn
tiếp nhận các yêu cầu Khi trình phục vụ nhận một
yêu cầu, nó sẽ tạo một tiến trình mới để phục vụ
yêu cầu đó Phương pháp đa tiến trình này là cách
sử dụng thông thường trước khi luồng trở nên phổ
biến Tuy nhiên, việc tạo ra tiến trình chiếm nhiều
tài nguyên và thời gian của hệ thống
Nếu tiến trình mới sẽ thực hiện cùng tác vụ như
tiến trình đã có thì tại sao lại phải chịu tất cả chi
phí đó? Thường sẽ hiệu quả hơn cho một tiến trình
gồm nhiều luồng phục vụ cùng một mục đích Tiếp cận này sẽ đa luồng hóa tiến trình máy chủ Web Tiến trình sẽ tạo một luồng riêng lắng nghe các yêu cầu; khi yêu cầu được thực hiện nó không tạo ra tiến trình khác mà sẽ tạo một luồng khác xử lý yêu cầu
Ưu điểm của đa luồng:
Khả năng đáp ứng: đa luồng một ứng dụng cho phép một chương trình tiếp tục chạy, thậm chí một phần của nó bị khóa hay đang thực hiện một thao tác dài Do đó cải thiện
sự đáp ứng đối với người dùng Ví dụ, máy chủ Web vẫn có thể đáp ứng yêu cầu của người dùng mới bằng một luồng trong khi yêu cầu của người dùng cũ đang được xử lý Chia sẻ tài nguyên: mặc định, các luồng chia sẻ bộ nhớ và các tài nguyên của các tiến trình mà chúng thuộc về Thuận lợi của việc chia sẻ mã là nó cho phép một ứng dụng
có nhiều hoạt động của các luồng khác nhau nằm trong cùng không gian địa chỉ Kinh tế: cấp phát bộ nhớ và các tài nguyên cho việc tạo các tiến trình là rất đắt Vì các luồng chia sẻ tài nguyên của tiến trình mà chúng thuộc về nên nó kinh tế hơn để tạo và chuyển ngữ cảnh giữa các luồng Khó để đánh giá theo kinh nghiệm sự khác biệt chi phí cho việc tạo và duy trì một tiến trình hơn một luồng, nhưng thường nó sẽ mất nhiều thời gian để tạo và quản lý một tiến trình hơn một luồng Ví dụ, trong hệ điều hành Sun Solaris 2, tạo một tiến trình chậm hơn khoảng 30 lần tạo một luồng và chuyển đổi ngữ cảnh chậm hơn 5 lần
Khai thác kiến trúc đa xử lý: các lợi điểm của đa luồng có thể phát huy trong kiến trúc
đa xử lý, ở đó mỗi luồng thực thi song song trên một bộ xử lý khác nhau Một tiến trình đơn luồng chỉ có thể chạy trên một CPU Đa luồng trên một máy nhiều CPU gia tăng tính đồng hành Trong kiến trúc đơn xử lý, CPU thường chuyển đổi qua lại giữa mỗi luồng quá nhanh để tạo ra hình ảnh của sự song song nhưng trong thực tế chỉ một luồng đang chạy tại một thời điểm
Luồng người dùng và luồng nhân:
Chúng ta vừa mới thảo luận là xem xét luồng như một chiều hướng chung Tuy nhiên,
hỗ trợ luồng được cung cấp hoặc ở cấp người dùng, cho các luồng người dùng hoặc ở cấp nhân, cho các luồng nhân
Luồng người dùng: được hỗ trợ dưới nhân và được cài đặt bởi thư viện luồng tại cấp người dùng Thư viện cung cấp hỗ trợ cho việc tạo luồng, lập thời biểu, và quản lý
Hình vẽ: Tiến trình đa luồng với
hệ thống một bộ xử lý
Trang 9mà không có sự hỗ trợ từ nhân Vì nhân không biết các luồng cấp người dùng, tất cả việc tạo luồng và lập thời biểu được thực hiện trong không gian người dùng mà không cần sự can thiệp của nhân Do đó, các luồng cấp người dùng thường tạo và quản lý nhanh, tuy nhiên chúng cũng có những trở ngại Ví dụ, nếu nhân là đơn luồng thì bất cứ luồng cấp người dùng thực hiện một lời gọi hệ thống nghẽn sẽ làm cho toàn bộ tiến trình bị nghẽn
Luồng nhân: được hỗ trợ trực tiếp bởi hệ điều hành Nhân thực hiện việc tạo luồng, lập thời biểu, và quản lý không gian nhân Vì quản lý luồng được thực hiện bởi hệ điều hành, luồng nhân thường tạo và quản lý chậm hơn luồng người dùng Tuy nhiên,
vì nhân được quản lý các luồng nếu một luồng thực hiện lời gọi hệ thống nghẽn, nhân
có thể lập thời biểu một luồng khác trong ứng dụng thực thi Trong môi trường đa xử
lý, nhân có thể lập thời biểu luồng trên một bộ xử lý khác Hầu hết các hệ điều hành hiện nay như Windows NT, Windows 2000, Solaris 2, BeOS và Tru64 UNIX (trước Digital UNIX) – hỗ trợ các luồng nhân
Tín hiệu ngắt được phần cứng xử lý Khi xảy ra ngắt, trình tự thực hiện như sau:
Bước 1: Điều khiển chuyển cho hệ điều hành
Bước 2: Hệ điều hành lưu lại trạng thái của tiến trình bị ngắt Trong nhiều hệ thống
thì thông tin đó được lưu trong PCB của tiến trình bị ngắt
Bước 3: Hệ điều hành phân tích loại ngắt và chuyển điều khiển cho chương trình xử
lý ngắt tương ứng
Bước 4: Tác nhân gây ra ngắt có thể là chính bản thân tiến trình đang chạy, hay là một
sự kiện có thể liên quan hoặc không liên quan đến tiến trình đó
Trang 10Bài 2: Quản lý tiến trình
Dạng 4 Restart Interrupt
Sinh ra khi người điều kiển cần khởi động lại hệ thống, hay lệnh Restart SIGP của một
bộ xử lý khác trong hệ thống đa bộ xử lý
Dạng 5 Program check Interrupt
Ngắt sinh ra do lỗi hoạt động của chương trình ví dụ lệnh chia cho 0,
Dạng 6 Machine check Interrupt
Sinh ra do lỗi phần cứng trong hệ thống
2.1.6.2 Chuyển ngữ cảnh – (Context Switching)
Để xử lý các loại ngắt, trong hệ điều hành có chương trình chuyên biệt gọi là Interrupt Handler Như trên đã nêu, trong hệ thống có 6 loại ngắt, như thế trong hệ điều hành có
6 IH (Interrupt Handler) để xử lý 6 loại ngắt khác nhau Khi có ngắt thì hệ điều hành ghi lại trạng thái của tiến trình bị ngắt và chuyển điều khiển cho chương trình xử lý ngắt tương ứng Điều đó được thực hiện bởi phương pháp gọi là “chuyển ngữ cảnh” (Context Switching)
Trong phương pháp này sử dụng các thanh ghi trạng thái chương trình PSW (Program status word), trong đó chứa thứ tự thực hiện lệnh và các thông tin khác nhau liên quan đến trạng thái của tiến trình Có 3 loại PSW:
PSW hiện thời (Current)
PSW mới (New)
PSW cũ (Old)
Địa chỉ của lệnh tiếp theo (sẽ được thực hiện) được chứa trong Current PSW, trong Current PSW cũng chứa thông tin về những loại Interrupt nào hiện đang bị cấm (Disable) hay được phép (Enable) Bộ xử lý chỉ phản ứng với những loại ngắt được phép, còn các ngắt đang bị cấm sẽ được xử lý sau hoặc bỏ qua Có một số Interrupt không bao giờ bị cấm: SVC, Restart,
Trong hệ có một bộ xử lý thì chỉ có một Current PSW, nhưng có 6 New PSW (tương ứng cho mỗi loại ngắt) và 6 Old PSW tương ứng New PSW của một loại ngắt chứa địa chỉ của chương trình xử lý ngắt (Interrupt Handler) loại đó
Khi xảy ra ngắt (nếu loại ngắt đó không bị cấm), lúc đó sẽ tự động (do phần cứng thực hiện) xảy ra tiến trình chuyển đổi PSW như sau:
Trang 11 Current PSW trở thành Old PSW của loại ngắt tương ứng
New PSW của loại ngắt đó trở thành Current PSW
Như thế, sau khi chuyển đổi thì Current PSW chứa địa chỉ của chương trình xử lý ngắt và sau đó chương trình xử lý ngắt sẽ được thực hiện
Khi kết thúc chương trình xử lý ngắt, bộ xử lý lại hoạt động bình thường, bộ xử lý sẽ tiếp tục phục vụ tiến trình bị ngắt hoặc có thể một tiến trình khác trong danh sách các tiến trình sẵn sàng
Trong trường hợp tiến trình không cho phép giải phóng (nhường) quyền sử dụng bộ
xử lý thì nó sẽ tiếp tục được bộ xử lý phục vụ, còn nếu nó cho phép thì nó tiếp tục được sử dụng bộ xử lý khi không có tiến trình sẵn sàng nào
Trong các hệ thống, có nhiều mô hình xử lý ngắt khác nhau không hoàn toàn như mô hình trên
Kiến trúc phân cấp của hệ thống
Trong việc thiết kế hệ điều hành, phương pháp xây dựng hệ điều hành phân cấp thành nhiều khối có nhiều ưu điểm Tầng thấp nhất của kiến trúc thường là phần cứng, ở các lớp tiếp theo thường là các module với các chức năng khác nhau của hệ điều hành Tổng hợp các module của Kernel ta có máy tính mở rộng (Extended Machine), nhờ đó
hệ thống cung cấp nhiều dịch vụ khác nhau cho người dùng Các chức năng mở rộng
đó (do Kernel cung cấp) được gọi là các Primitive
Phía trên Kernel là các tiến trình hệ thống (System Process) của hệ điều hành để phục
vụ cho các tiến trình của người dùng Còn trên cùng là các tiến trình của người sử dụng (User Process)
Kinh nghiệm cho thấy kiến trúc lớp làm cho công việc thiết kế, sửa đổi, Test dễ dàng hơn Trong hệ thống mà Kernel gồm nhiều lớp, thì cần xem xét cẩn thận chức năng nào nằm ở lớp nào Trong các hệ đó thường người ta hạn chế cho phép truy xuất từ trên xuống tức là tại mỗi lớp chỉ có thể thâm nhập đến lớp dưới kế tiếp mà thôi
Hạt nhân của OS
Khái niệm: Tất cả các thao tác liên quan đến tiến trình, thực hiện bởi một phần hệ
điều hành gọi là hạt nhân – Kernel
Kernel chỉ là một phần không lớn (về kích thước Code) của hệ điều hành nhưng nó là một trong số những thành phần được sử dụng nhiều nhất trong hệ điều hành Do đó Kernel thường luôn được nạp vào bộ nhớ, trong khi các thành phần khác có thể nằm ở
bộ nhớ ngoài và chỉ được nạp vào khi cần
Chức năng: Một trong những chức năng quan trọng nhất trong Kernel là xử lý ngắt
Trong các hệ lớn nhiều thành phần (Component) thường xuyên có dòng lớn (nhiều) ngắt Do đó xử lý ngắt nhanh đóng vai trò quan trọng trên quan điểm sử dụng tài nguyên hệ thống và đảm bảo thời gian phản ứng với các yêu cầu của người dùng một cách nhanh chóng
Khi Kernel xử lý ngắt, nó cấm các ngắt khác và chỉ cho phép tiếp tục xử lý ngắt sau khi xử lý xong ngắt hiện thời
Trong trường hợp có dòng liên tục các ngắt thì có thể xuất hiện tình huống các ngắt bị chặn trong thời gian tương đối lớn tức là hệ thống không phản ứng kịp thời với các sự
Trang 12Bài 2: Quản lý tiến trình
kiện Do đó Kernel thường được thiết kế sao cho nó chỉ thực hiện việc tiền xử lý tối thiểu và chuyển việc xử lý tiếp theo cho tiến trình hệ thống (System Process) tương ứng và có thể cho phép xử lý các ngắt tiếp theo Theo đó các ngắt bị cấm trong khoảng thời gian nhỏ hơn do đó tốc độ phản ứng của hệ thống tăng đáng kể
Các chức năng chính của Kernel
Kernel thường gồm các chương trình thực hiện các chức năng sau:
Xử lý ngắt
Tạo và xoá các tiến trình
Đổi trạng thái của tiến trình
Cho phép (Enable) và cấm (Diasable) ngắt
Xâm nhập Kernel thường được thực hiện thông qua ngắt, khi Kernel phản ứng với ngắt nào đó thì nó cấm các ngắt khác Sau khi phân tích nó chuyển việc xử lý cho một tiến trình hệ thống chuyên làm việc với loại ngắt đó
Trong một số hệ thống mỗi ngắt đều đươc xử lý bởi cả hệ điều hành cồng kềnh, do đó các ngắt thường bị cấm trong phần lớn thời gian nhưng về nguyên tắc hệ điều hành lại đơn giản hơn Cách này thường áp dụng cho các máy nhỏ, làm việc với ít tiến trình Còn với các hệ thống phức tạp, thường có một phần hệ điều hành chuyên xử lý ngắt cho phép nâng cao các chỉ số của cả hệ thống
Thực hiện Kernel với MicroCode
Xu hướng: thiết kế nhiều chức năng với MicroCode đó là cách hiệu quả bảo vệ
Kernel ngoài ra viết MicroProgram tốt có thể nâng cao tốc độ của cả hệ thống Tất nhiên đổi lại việc thiết kế phức tạp hơn rất nhiều
Các tiến trình gọi là đồng thời/tương tranh nếu các tiến trình đó tồn tại đồng thời Các tiến trình tương tranh (Concurent Process) có thể hoạt động hoàn toàn độc lập với nhau hoặc song song không đồng bộ (Asynchronous), tức là theo chu kỳ chúng cần đồng bộ và tương tác với nhau Song song không đồng bộ (Asynchronism) là một vấn
đề phức tạp
Chúng ta sẽ xem xét một số vấn đề liên quan đến điều khiển các tiến trình tương tranh không đồng bộ (Asynchronous Concurent Process) Các ví dụ được đưa ra với ngôn ngữ giả Pascal Một số ví dụ về ngôn ngữ cho phép lập trình song song là ngôn ngữ Modula (Nicolar Witt), ngôn ngữ Ada
Trang 132.2.2 Xử lý song song
Theo sự phát triển của máy tính chúng ta có thấy sự phổ biến của các hệ thống đa xử
lý (MultiProcessor) và cùng với nó là sự phổ biến của xử lý song song Nếu như một tiến trình Logic có thể xử lý song song Logic thì các hệ thống mới có thể xử lý chúng song song thực sự và có thể công việc được phân chia giữa các bộ xử lý khác nhau
Xử lý song song là vấn đề được quan tâm và có nhiều khó khăn do một loạt nguyên nhân khác nhau Con người theo tự nhiên có xu hướng chỉ chú ý đến một công việc tại mỗi thời điểm hơn là nghĩ đến nhiều việc khác nhau cùng một lúc Thông thường khó
mà xác định những thao tác nào có thể thực hiện song song và theo dõi một chương trình song song khó hơn nhiều so với chương trình xử lý tuần tự
Các tiến trình song song không đồng bộ cần tương tác qua lại lẫn nhau theo chu kỳ thời gian và tương tác này có thể khá phức tạp Cuối cùng, việc chứng tỏ sự đúng đắn cho các chương trình song song khó hơn nhiều so với trường hợp chương trình tuần tự
và chúng ta cũng quan tâm đến phương pháp hiệu quả để chứng minh tính đúng đắn của chương trình, có như thế chúng ta mới có thể xây dựng các hệ thống có tính ổn định cao
Các lệnh chỉ thị xử lý song song: parbegin và parend
Trong nhiều ngôn ngữ lập trình đã có các chỉ thị yêu cầu xử lý song song (như trong Ada, Modula, ) các chỉ thị này thường đi theo cặp:
Chỉ thị đầu tiên chỉ ra rằng bắt đầu từ sau lệnh đó, chương trình được tách thành một
số dòng điều khiển (Thread Control) thực hiện song song
Chỉ thị thứ hai chỉ ra rằng từ đó chương trình lại được xử lý tuần tự
Có nhiều tên khác nhau nhưng người ta thường dùng cặp parbegin/parend (Dijktra – Cooperating Sequenical Process) Nói chung đoạn mã chương trình được thực hiện song song có dạng:
xử lý sẽ được chia thành n tiến trình xử lý độc lập, mỗi tiến trình sẽ xử lý một thao tác tương ứng từ operator 1, đến operator n Thao tác này có thể là các lệnh đơn, lời gọi hàm, khối các lệnh tuần tự nằm giữa begin/end hay là tổ hợp các thao tác đó
Các tiến trình xử lý sẽ dần thực hiện đến lệnh parend lúc đó luồng điều khiển lại hợp nhất thành một luồng xử lý các lệnh tiếp theo một cách tuần tự
Ví dụ:
Xét biểu thức: x:= (–b + (b2 – 4*a*c) * 5) / (2*a)
Giải: Nếu tiến trình xử lý là hoàn toàn tuần tự chúng ta có thể làm theo các bước sau:
b2 4*a (4*a)*c
Trang 14Bài 2: Quản lý tiến trình
b2–(4*a*c) (b2–(4*a*c))*5 – b
– b+((b2–(4*a*c))*5) 2*a
(– b+(b2–(4*a*c))*5))/(2*a) Các bước xử lý trên theo đúng trình tự quy tắc thực hiện phép toán
Với hệ thống hỗ trợ xử lý song song chúng ta có thể làm như sau:
parbegin temp1:= –b temp2:= b2 temp3:= 4*a temp4:= 2*a parend temp5:= temp3*c temp5:= temp2–temp5 temp5:= temp5*5 temp5:= temp1+temp5 x:= temp5/temp4
Ta thấy nếu thực hiện xử lý song song thì thời gian tính toán giảm đi đáng kể so với khi tính tuần tự
Loại trừ lẫn nhau chỉ cần thiết trong trường hợp khi các tiến trình cùng truy nhập đến dữ liệu chung, hay khi chúng thực hiện các thao tác có thể dẫn tới tranh chấp (conflic) dữ liệu nói chung, còn khi chúng thực hiện các thao tác operation không dẫn tới tranh chấp thì hoàn toàn có thể thực hiện song song đồng thời Khi tiến trình truy nhập đến dữ liệu chung thì người ta nói rằng lúc đó tiến trình nằm trong khoảng tới hạn (Critical Region)
Rõ ràng là để giải quyết tranh chấp thì khi có một tiến trình nằm trong khoảng tới hạn, cần phải không cho phép tiến trình khác (ít nhất là các tiến trình truy nhập đến cùng một dữ liệu) được vào khoảng tới hạn (tất nhiên chúng vẫn có thể thực hiện các thao tác khác ngoài khoảng tới hạn) Còn khi tiến trình ra khỏi khoảng tới hạn thì một trong
số các tiến trình đang chờ vào khoảng tới hạn phải được tiếp tục vào khoảng tới hạn Đảm bảo 'loại trừ lẫn nhau' là một trong những vấn đề mấu chốt của lập trình xử lý song song Có nhiều phương pháp được đề xuất từ thực hiện hoàn toàn bằng phần mềm đến thực hiện bằng phần cứng, từ mức thấp đến mức cao, có những phương pháp cho phép loại trừ lẫn nhau trong điều kiện tương đối thoải mái, còn có những phương pháp thì bắt buộc phải có thêm các điều kiện chặt chẽ
Khi một tiến trình nằm trong khoảng tới hạn thì có nhiều vấn đề cần quan tâm Trong chế độ này nó có toàn quyền truy nhập dữ liệu chung còn các tiến trình khác phải chờ
Do đó các tiến trình cần ra khỏi chế độ này càng nhanh càng tốt, trong chế độ này nó không được chuyển sang trạng thái Blocked, do đó các khoảng tới hạn cần thiết kế, kiểm tra cẩn thận (ví dụ không cho phép xảy ra vòng lặp chờ trong khoảng tới hạn ) Khi tiến trình kết thúc (ra khỏi) khoảng tới hạn (bình thường hoặc ngay cả khi có lỗi) thì hệ điều hành phải kiểm soát được để huỷ bỏ chế độ tới hạn, nhờ thế các tiến trình khác có thể đến lượt vào khoảng tới hạn
Trang 15Mutual Exclusion Primitive
Chương trình song song dưới đây đảm bảo bài toán trong mục 2.2.2 hoạt động đúng
Từ đây trở đi chúng ta xét trường hợp chỉ có hai tiến trình song song, cần phải nói rằng trường hợp có n tiến trình (n > 2) thì bài toán phức tạp hơn rất nhiều
Trong chương trình 1 chúng ta dùng hai chỉ thị: Enter Mutual Exclusion và Exit Mutual Exclusion trong mỗi tiến trình ở đoạn Code truy nhập đến dữ liệu chung (biến toàn cục Total Line), hai chỉ thị này bao hai đầu khoảng tới hạn Đôi khi các chỉ thị này được gọi là Mutual Exclusion Primitive
Chương trình 1
Program MutualExclusionSample var
totalLine:integer;
procedure Process1 begin
while True do begin get line {readln}
while True do begin get line {readln}
Trong trường hợp có hai tiến trình, các lệnh Primitive làm việc như sau:
khi tiến trình 1 thực hiện chỉ thị Enter Mutual Exclusion và lúc đó tiến trình 2 ở ngoài khoảng tới hạn thì nó được vào khoảng tới hạn, thực hiện các lệnh trong khoảng tới hạn và đến khi thực hiện lệnh Exit Mutual Exclusion là lúc báo hiệu nó ra khỏi khoảng tới hạn
Trang 16Bài 2: Quản lý tiến trình
Còn nếu khi tiến trình 1 muốn vào khoảng tới hạn, trong lúc đó tiến trình 2 đã ở trong khoảng tới hạn thì tiến trình 1 nó phải chờ đến khi tiến trình 2 ra khỏi khoảng tới hạn
để có thể tiếp tục vào khoảng tới hạn
Nếu cả hai tiến trình thực hiện Enter Mutual Exclusion cùng một lúc thì một trong hai tiến trình sẽ được phép vào khoảng tới hạn còn tiến trình kia sẽ phải chờ, có thể sự lựa chọn là ngẫu nhiên
Xét trường hợp hệ thống phục vụ trong chế độ phân chia thời gian cho nhiều thiết bị đầu cuối – Terminal Giả sử khi người sử dụng đánh hết một dòng và gõ Enter, cần tính số dòng của tất cả các người sử dụng đã gõ từ tất cả các terminal Để thực hiện điều đó, mỗi khi một người sử dụng nào đó gõ Enter thì tiến trình của người dùng đó
sẽ tăng thêm 1 đơn vị cho một biến toàn cục (Global) Total Line Vì hệ thống là đa xử
lý và đa người dùng, do đó hoàn toàn có khả năng là hai người dùng khác nhau gõ Enter gần như đồng thời, khi đó 2 tiến trình điều khiển ứng với 2 người dùng đó sẽ đồng thời muốn truy nhập đến biến toàn cục Total Line Để tăng biến đó giả sử mỗi tiến trình ứng dụng đều dùng các lệnh sau:
1– load totalline 2– totalline:= totalline + 1 3– store totalline
Giả sử tại một thời điểm, totalline có giá trị 62829
Bây giờ nếu mới tiến trình 1 thực hiện được 2 lệnh đầu tiên:
load totalline (đọc giá trị hiện thời của biến) và tăng 1 cho giá trị biến totalline := totalline + 1 khi đó trong một thanh ghi (ví dụ Ax) chứa giá trị mới 62830 của biến totalline
Sau đó tiến trình 1 không được quyền sử dụng bộ xử lý nữa (ví dụ do ngắt thời gian)
và đến lượt tiến trình 2 được thực hiện Giả sử tiến trình 2 kịp thực hiện cả 3 lệnh trên, khi đó giá trị của biến totalline sau khi thực hiện xong sẽ có giá trị 62830 Sau đó điều khiển được trả lại cho hệ điều hành và đến lượt tiến trình 1 được tiếp tục, nó thực hiện nốt lệnh thứ 3 tức là ghi lại giá trị 62830 vào biến totalline Chúng ta thấy do sự điều khiển truy xuất không đúng mà chương trình hoạt động không đúng
Ta thấy rằng vấn đề này có thể khắc phục nếu mỗi tiến trình có quyền truy nhập duy nhất đến biến totalline, tức là khi một tiến trình đang truy nhập đến biến totalline thì các tiến trình khác phải đợi đến khi tiến trình đầu tiên kết thúc truy nhập
Như thế, khi một tiến trình truy nhập đến dữ liệu chung thì cần cấm tất cả các tiến trình khác truy nhập đến cùng dữ liệu vào thời điểm đó Điều đó gọi là loại trừ lẫn nhau (Mutual Exclusion)
Chúng ta sẽ tìm cách thực hiện các Primitive Enter và Exit với các hạn chế sau:
Vấn đề giải quyết hoàn toàn bằng chương trình (phần mềm) trên hệ thống không
có lệnh chuyên cho loại trừ lẫn nhau Mỗi lệnh được thực hiện trọn vẹn không bị ngắt giữa chừng Khi có nhiều tiến trình cùng muốn truy nhập đến dữ liệu chung thì tranh chấp được giải quyết bằng phần cứng, một cách tình cờ sẽ có một tiến trình được chọn
Trang 17 Không có bất cứ giả sử gì về tốc độ tương đối của các Asynchronous parallel Process
Các tiến trình nằm ngoài khoảng tới hạn không thể cấm các tiến trình khác vào khoảng tới hạn
Không được để tiến trình chờ vô hạn để vào khoảng tới hạn
Cơ chế thực hiện loại trừ lẫn nhau bằng chương trình được nhà toán học Hà lan Dekker đề ra đầu tiên Chúng ta sẽ xem xét các Version của thuật toán Dekker do Dijkstra thực hiện
Thuật toán Dekker
Version 1:
Đầu tiên, chúng ta xem xét Version đầu tiên
Có thể coi mỗi tiến trình như là một vòng lặp vô tận với nhiều lần lặp vào chế độ Mutual Exclusion Trong Version này Primitive Enter Mutual Exclusion được thực hiện nhịp vòng lặp While chờ đến khi biến Processno bằng số của tiến trình, còn Primitive Exit Mutual Exclusion thực hiện như một lệnh đặt biến Processno bằng số của tiến trình khác
Chương trình 1
Program Version1 var
ProcessNo:integer;
procedure Process1 begin
while True do begin
while ProcessNo = 2 do ; {Critical Region}
while True do begin
while ProcessNo = 1 do ; {Critical Region}
Trang 18Bài 2: Quản lý tiến trình
Hoạt động: Cả hai tiến trình cùng thực hiện
Vì đầu tiên biến ProcessNo gán bằng 1 do đó chỉ tiến trình 1 được vào Critical Region
Tiến trình 2 khi muốn vào Critical Region kiểm tra thấy biến Processno có giá trị 1
do đó nó phải chờ bằng vòng lặp rỗng, nó chờ đến khi ProcessNo :=2 tức là khi tiến trình 1 ra khỏi Critical Region và đặt ProcessNo :=2
Vậy chương trình đã đảm bảo loại trừ lẫn nhau (Mutual Exclusion)
Nhược điểm: Version1 có nhiều nhược điểm, tiến trình 1 phải vào Critical Region
trước tiên (tức là dù tiến trình 2 sẵn sàng trước thì nó vẫn phải chờ) và các tiến trình lần lượt vào Critical Region theo thứ tự cố định (do đó nếu một tiến trình thực hiện các lệnh trong Critical Region thường xuyên hơn thì nó phải làm việc với tốc độ chậm hơn nhiều)
Chương trình này đảm bảo không rơi vào tình trạng Deadlock vì khi cả hai tiến trình cùng muốn vào Critical Region thì có ít nhất một tiến trình tiếp tục Còn khi một tiến trình kết thúc thì sau đó tiến trình còn lại cũng kết thúc
Version 2:
Trong Version 1 việc thực hiện Mutual Exclusion chỉ bằng một biến do đó có vấn đề các tiến trình vào khoảng tới hạn theo thứ tự cố định Để cải tiến, trong Version 2 sử dụng hai biến Logic: flag1 và flag2, chúng nhận giá trị True khi tiến trình tương ứng nằm trong Critical Region
Trong Version này tiến trình 1 chủ động chờ (Active wait) trong khi biến flag2 vẫn
là True Khi tiến trình 2 ra khỏi khoảng tới hạn, nó đặt lại flag2 := False và do đó tiến trình 1 ra khỏi vòng chờ while, đặt biến flag1 := True và vào khoảng tới hạn Khi flag1 còn là True thì tiến trình 2 không thể vào khoảng tới hạn
Chương trình 2
Program Version2 var
flag1, flag2:boonlean;
procedure Process1 begin
while True do begin
while flag2 = True do ;
while True do begin
while flag1 = True do ;
Trang 19Nhưng lại xuất hiện một số vấn đề liên quan đến lập trình song song Vì tiến trình 1
và tiến trình 2 là song song do đó chúng có thể đồng thời thử vào Critical Region Đầu tiên các biến flag1 và flag2 có giá trị False Tiến trình 1 kiểm tra biến flag2 thấy flag2 := False và thoát khỏi vòng lặp chờ, trước khi nó kịp đặt flag1 thành True bằng lệnh flag1 := True thì đến lượt tiến trình 2 được chiếm bộ xử lý, tiến trình 2 cũng có thể kiểm tra thấy flag1 là False (vì lúc đó tiến trình 1 chưa kịp đặt) lúc đó tiến trình 2 đặt flag2 := True và cũng vào Critical Region Như thế cả hai tiến trình cùng vào chế độ Critical, do đó Version 2 không đảm bảo loại trừ lẫn nhau
Nhược điểm: Điểm yếu của Version 2 là giữa thời điểm khi tiến trình nằm trong
vòng chờ xác định thấy nó có thể đi tiếp và thời điểm nó đặt cờ (biến flag) nói rằng
nó đã vào Critical Region Do đó cần thiết để vào lúc tiến trình kết thúc vòng lặp chờ, tiến trình khác không thể ra khỏi vòng lặp chờ
flag1,flag2:boonlean;
procedure Process1 begin
while True do begin
while True do begin
Trang 20Bài 2: Quản lý tiến trình
flag2:= True while flag1 = True do ; {Critical Region}
vô tận Chương trình này là một ví dụ của khái niệm Deadlock – tắc nghẽn
Nhược điểm: Điểm yếu của Version 3 là ở chỗ mỗi tiến trình đều có thể bị Block
ở vùng chờ Chúng ta cần có biện pháp thoát khỏi vòng chờ này
flag1,flag2:boonlean;
procedure Process1 begin
while True do begin
while True do begin
flag2:= True while flag1 = True do begin
Trang 21Nhược điểm: Thoạt xem, Version4 đảm bảo sự loại trừ lẫn nhau và không bị
Deadlock, nhưng lại xuất hiện vấn đề khác cũng rất quan trọng là vòng chờ vô tận Chúng ta xét xem tại sao điều đó xảy ra Vì chúng ta không có giả sử gì về tốc độ tương đối giữa các tiến trình do đó có thể có trường hợp các tiến trình lần lượt thực hiện dãy thao tác như sau trong một interval:
1 Đặt cờ flag giá trị True, vào vòng lặp chờ
2 Đặt lại cờ flag giá trị False, chờ random
3 Lại đặt cờ giá trị True và lặp lại tiến trình trong vòng chờ
Khi đó các tiến trình thực hiện xong tất cả các thao tác đó, điều kiện kiểm tra luôn đúng và không thể thoát khỏi vòng chờ Mặc dù trường hợp đó rất hiếm nhưng về nguyên tắc là có thể, do đó Version 4 cũng không thể áp dụng ví dụ như trong hệ thống điều khiển chuyến bay vũ trụ, dù xác suất nhỏ
Thuật toán Dekker:
Như thế chúng ta cần khắc phục sự chờ vô tận Thuật toán Dekker loại trừ tình trạng chờ vô tận trong Version 4 Với một số lượng không lớn Code, chương trình theo thuật toán của Dekker cho phép giải quyết triệt để vấn đề loại trừ lẫn nhau cho hai tiến trình, không đòi hỏi các lệnh đặc biệt nào
Chương trình 5
Program Dekker var
flag1, flag2go: boonlean;
selection: byte; {set of 1,2}
procedure Process1 begin
while True do begin
while flag2 = True do begin
if selection = 2 then begin flag1:= False;