You are on page 1of 57

Tiến trình (Processes)

2.1 Giới thiệu về tiến trình (Introduction to processes)

Tất cả máy tính hiện đại có thể làm một vài thứ cùng một lúc. Trong khi
chạy một chương trình người sử dụng, một máy tính cũng có thể được
đọc từ một ổ đĩa và in trên một thiết bị đầu cuối hoặc máy in. Trong một
hệ thống multiprogramming, CPU cũng chuyển từ chương trình đến
chương trình, mỗi lần chạy trong hàng chục hoặc hàng trăm phần nghìn
mili giây. Trong khi, nói đúng ra, tại bất kỳ thời điểm nào, CPU đang
chạy chỉ có một chương trình, trong quá trình của 1 giây, nó có thể làm
việc trên một số chương trình, do đó điều này đem lại cho người sử dụng
những ảo ảnh của sự tương đương. Đôi khi người ta nói về sự tương
đương giả để nói lên sự chuyển đổi nhanh về phía sau và phía trước của
CPU giữa các chương trình, để làm khác biệt nó với phần cứng thật tương
đương trong khi một hoặc nhiều thiết bị vào / ra đang chạy. Giữ việc theo
dõi nhiều các hoạt động song song thì thật khó để làm. Vì vậy, thiết kế hệ
điều hành trong những năm qua đã phát triển một mô hình mà làm song
song dễ dàng hơn để giải quyết. Mô hình đó là chủ đề của chương này.
2.1.1 The process model(Mô hình của tiến trình)

Trong mô hình này, tất cả các phần mềm có thể chạy được trên máy tính,
thường bao gồm cả hệ thống điều hành, được tổ chức thành một số quy
trình tuần tự, hoặc chỉ là quy trình tắt. Một tiến trình chỉ là một chương
trình thực hiện, bao gồm cả các giá trị hiện tại của chương trình truy cập,
đăng ký và biến số. Dựa trên các khái niệm đó, mỗi tiến trình đều có CPU
ảo của nó. Thực tế, tất nhiên các CPU thật chuyển mạch qua lại từng quá
trình một, nhưng để hiểu được hệ thống, thì sẽ dễ dàng hơn nhiều để nghĩ
về một tập hợp các tiến trình đang chạy song song(giả), hơn là cố gắng để
theo dõi CPU sẽ chuyển từng chương trình một như thế nào. Sự chuyển

1
đổi qua lại nhanh chóng này được gọi là đa chương trình như chúng ta đã
thấy trong các chương trước. Trong hình 2-1 (a) chúng ta thấy một máy
tính multiprograming bốn chương trình trong bộ nhớ.
Trong hình 2-1 (b) chúng ta thấy cách này được trừu tượng hóa thành bốn
tiến trình, mỗi tiến trình với dòng riêng của nó kiểm soát (ví dụ, chương
trình truy cập riêng của nó), và mỗi tiến trình hoạt động độc lập với
những cái khác. Trong hình 2-1 (c) chúng ta thấy rằng, qua một khoảng
thời gian đủ dài, tất cả các tiến trình đã thực hiện sự tiến triển, nhưng bất
cứ thời điểm nào được đưa ra thì chỉ có duy nhất một tiến trình là đang
thực sự chạy.
Với CPU chuyển đổi qua lại giữa các tiến trình, tốc độ mà 1 tiến trình
thực hiện tính toán sẽ không được thống nhất, và có lẽ thậm chí không tái
sản xuất nếu cùng một tiến trình như thế được chạy lại. do đó, tiến trình
không phải được lập trình với các giả định có sẵn về định thời. Có thể
xem xét, ví dụ, một tiến trình vào/ra mà khởi động một băng từ trong
chuyển động, thực hiện một vòng lặp nhàn rỗi 1000 lần để cho các băng
nhận được lên đến tốc độ, và sau đó cung cấp một lệnh để đọc bản ghi
đầu tiên. Nếu CPU quyết định chuyển sang 1 tiến trình khác trong vòng
nhàn rỗi, tiến trình băng có thể sẽ không chạy lại cho đến khi sau khi bản
ghi đầu tiên đã được chuyển sẵn qua đầu đọc. Khi một tiến trình có các
yêu cầu giới hạn thời gian thực như thế này, đó là, một số sự kiện tuyệt
đối phải xảy ra trong một số mili giây dự kiến, các biện pháp đặc biệt
phải được thực hiện để đảm bảo rằng chúng xảy ra. Thông thường, tuy
nhiên, hầu hết các tiến trình không bị ảnh hưởng bởi đa lập trình nằm
dưới của CPU hay tốc độ liên quan của các tiến trình khác nhau.
Điểm khác nhau giữa một tiến trình và một chương trình là tinh tế, nhưng
mang tính quyết định. Một sự tương đồng có thể giúp làm cho điểm này
rõ ràng hơn. Xem xét một nhà khoa học máy tính ẩm thực người nướng 1
chiếc bánh sinh nhật cho con gái của mình. Ông ta có một công thức làm

2
bánh sinh nhật và một nhà bếp được lưu trữ đầy đủ với các dụng cụ chuẩn
bị cần thiết: bột mì, trứng, đường, chiết xuất va ni và vân vân. Trong sự
tương đồng này, công thức là 1 chương trình (thí dụ, một thuật toán thể
hiện ở một số ký hiệu thích hợp), các nhà khoa học máy tính là bộ vi xử
lý (CPU), và các thành phần bánh là những dữ liệu đầu vào. Tiến trình là
hoạt động bao gồm thợ bánh mì đọc công thức, lấy các thành phần, và
nướng bánh.
Bây giờ tưởng tượng rằng con trai của nhà khoa học máy tính vừa
chạy vừa khóc, nói rằng nó đã bị một con ong đốt. Nhà khoa học máy
tính ghi lại nơi anh ta bị đốt vào trong công thức (các chế độ của tiến
trình hiện hành đã được lưu), lấy ra 1 cuốn sách hỗ trợ đầu tiên, và bắt
đầu theo các hướng dẫn trong đó. Ở đây chúng ta thấy bộ xử lý đã được
chuyển từ một tiến trình (nướng) cho một bộ xử lý ưu tiên cao hơn (quản
lý chăm sóc y tế), mỗi cái có một chương trình khác nhau (công thức đối
đầu với cuốn sách trợ giúp). Khi mà vết ong chích đã được chăm sóc,
nhà khoa học máy tính quay trở lại chiếc bánh của mình, tiếp tục tại các
điểm mà ông dừng lại.
Ý tưởng chính ở đây là một tiến trình là một hoạt động của một số loại.
Nó có một chương trình, đầu vào, đầu ra và một chế độ. Một bộ xử lý đơn
có thể được chia sẻ giữa một số tiến trình, với một số thuật toán lập lịch
trình được sử dụng để xác định khi nào dùng để ngăn chặn công việc của
1 tiến trình và dịch vụ một cáo khác.

Sự phân cấp tiến trình


Hệ thống điều hành mà hỗ trợ các khái niệm về tiến trình phải cung cấp
một số cách để tạo ra tất cả các tiến trình cần thiết. Trong các hệ thống rất
đơn giản, hoặc trong các hệ thống được thiết kế để chạy chỉ một ứng
dụng duy nhất, nó có thể có tất cả các tiến trình mà sẽ không bao giờ là
cần thiết có mặt khi các hệ thống đi lên. Trong hầu hết các hệ thống, tuy

3
nhiên, một số cách nào đó là cần thiết để tạo ra và phá hủy các tiến trình
là cần thiết trong quá trình hoạt động.
Trong UNIX, các tiến trình được tạo ra bởi hệ thống cuộc gọi FORK,
mà tạo ra một bản sao giống hệt nhau của quá trình gọi. Sau cuộc gọi
FORK, phần tử cấp trên tiếp tục chạy, song song với phần tử con. Sau đó
phần tử cha có thể phân nhánh thêm nhiều phàn tử con, do đó, bất cứ lúc
nào nó có thể có một số phần tử con thực hiện. Các phần tử con cũng có
thể thực hiện FORK, vì vậy nó có thể nhận được một cây toàn bộ tiến
trình, sâu một cách tùy ý.
Trong MS-DOS một cuộc gọi hệ thống tồn tại để tải một tập tin định
nhị phân vào bộ nhớ và thực hiện nó như là một tiến trình con. Trái
ngược với UNIX, trong MS-DOS cuộc gọi này làm ngưng tiến trình cha
cho đến khi tiến trình con đã hoàn thành thực hiện, do đó, tiến trình cha
và tiến trình con không chạy song song.
Các chế độ tiến trình
Mặc dù mỗi tiến trình là một thực thể độc lập, với bộ đếm chương trình
riêng của nó và chế độ bên trong, các tiến trình thường cần phải tương tác
với các tiến trình khác. Một tiến trình có thể phát sinh ra một số đầu ra
mà một tiến trình khác sử dụng như là đầu vào. Trong các lệnh shell tiến
trình đầu tiên, chạy cat, liên kết và đầu ra ba tập tin. Tiến trình này, chạy
grep, lựa chọn tất cả các dòng có chứa từ "cây". Tùy thuộc vào tốc độ
tương đối của hai tiến trình (mà phụ thuộc vào độ phức tạp tương đối của
cả hai chương trình và CPU mất bao lâu để mỗi chương trình có), nó có
thể xảy ra rằng grep đã sẵn sàng để chạy, nhưng không có đầu vào chờ
cho nó. Sau đó nó phải chặn cho đến khi một số đầu vào có sẵn.
Khi một tiến trình chặn, nó làm như vậy bởi vì nó không thể tiếp tục một
cách hợp lý, thường là bởi vì nó đang chờ đợi đầu vào mà chưa có sẵn.
Nó cũng có thể cho một tiến trình mà đó là khái niệm đã sẵn sàng và có
thể chạy, bị ngừng lại bởi vì hệ điều hành đã quyết định phân bổ CPU tới

4
1 tiến trình khác trong một lúc. Hai điều kiện này là hoàn toàn khác nhau.
Trong trường hợp đầu tiên, hệ thống treo là bản chất trong vấn đề (bạn
không thể xử lý dòng lệnh của người sử dụng cho đến khi nó đã được
đánh máy). Trong trường hợp thứ hai, nó là một công nghệ của hệ thống
(các CPU không đủ để cho mỗi tiến trình bộ vi xử lý riêng của nó). Trong
hình 2-2 chúng ta thấy một biểu đồ hiển thị ba trạng thái là một tiến trình
có thể là:
- Chạy (thực tế sử dụng CPU ở ngay thời điểm đó)
- Sẵn sàng (Runnable: tạm thời dừng lại để cho một tiến trình khác
chạy)
- Bị chặn (không thể chạy cho đến khi một sự kiện xảy ra bên
ngoài).
Đáng lý, hai trạng thái đầu tiên phải tương tự nhau. Trong cả hai
trường hợp tiến trình sẵn sàng để chạy, chỉ trong một giây, tạm
thời không có CPU nào có sẵn cho nó. Chế độ thứ ba là khác so
với hai cái trước đó rằng trong đó tiến trình không thể chạy, thậm
chí nếu CPU không có gì khác để làm.
Bốn sự chuyển đổi là có thể giữa ba chế độ, như được hiển thị.
Chuyển đổi xảy ra khi một tiến trình phát hiện ra rằng nó không
thể tiếp tục. Trong một số hệ thống tiến trình phải thực hiện một
cuộc gọi hệ thống, Block, để chuyển sang chế độ chặn. Thường,
khi một tiến trình đọc từ một mạch hoặc tập tin đặc biệt (ví dụ,
một thiết bị đầu cuối) và không có đầu vào có sẵn, tiến trình này
sẽ tự động bị chặn.
Sự chuyển tiếp 2 và 3 là do lịch trình (một phần của hệ điều
hành), thậm chí không có tiến trình biết về chúng. Chuyển đổi 2
xảy ra khi lịch trình quyết định rằng tiến trình chạy đã chạy thời
gian đủ dài, và đó là lúc để cho một tiến trình khác có một số thời
gian của CPU. Chuyển tiếp 3 xảy ra khi tất cả các tiến trình khác

5
đã có chia sẻ của chúng và đó là lúc cho tiến trình đầu tiên chạy lại
một lần nữa. Chủ đề của lịch trình, đó là, quyết định tiến trình nào
nên chạy khi nào và trong bao lâu, đó là 1 điều quan trọng, chúng
tôi sẽ xem xét nó sau trong chương này. Nhiều thuật toán đã được
đưa ra thử để cân đối hiệu quả của các lệnh cạnh tranh cho các HỆ
THỐNG như một toàn bộ và công bằng cho các tiến trình cá nhân.
Chuyển đổi 4 xảy ra khi sự kiện bên ngoài cho một tiến trình
chờ đợi (chẳng hạn như sự xuất hiện của một số đầu vào) sẽ xảy
ra. Nếu không có tiến trình khác đang chạy ngay lúc đó, chuyển
đổi 3 sẽ được kích hoạt ngay lập tức, và tiến trình sẽ bắt đầu chạy.
Nếu không thì nó có thể phải chờ trong trạng thái sẵn sàng trong
một lúc cho đến khi CPU có sẵn.
Sử dụng mô hình quy trình, nó trở nên dễ dàng hơn để nghĩ về
những gì đang xảy ra bên trong hệ thống. Một số các quá trình
chạy chương trình đó thực hiện bởi lệnh gõ vào của người sử
dụng. Các tiến trình khác là một phần của hệ thống và xử lý các
tác vụ như thực hiện các yêu cầu cho các dịch vụ tập tin hoặc quản
lý các chi tiết của việc chạy trên một ổ đĩa hoặc ổ đĩa băng. Khi
một ổ đĩa bị gián đoạn xảy ra, hệ thống ra quyết định ngừng chạy
tiến trình hiện tại và chạy tiến trình đĩa, mà đã bị chặn để chờ cho
việc ngắt. Do đó, thay cho việc nghĩ về sự ngắt, chúng ta có thể
nghĩ về tiến trình người sử dụng, các tiến trình đĩa, các tiến trình
thiết bị đầu cuối, và vân vân, cái mà chặn khi chúng đang chờ đợi
một cái gì đó xảy ra. Khi khối đĩa đã được đọc hoặc các ký tự đã
được đánh máy, tiến trình chờ cho nó không bị chặn nữa và có đủ
điều kiện để chạy lại.
Quan điểm này cho phép tăng tới mô hình thể hiện trong hình 2-3. Ở
đây, tầng chậm nhất của hệ điều hành là bộ lịch trình, với một loạt
các tiến trình khác đứng đầu. Tất cả các xử lý ngắt và các chi tiết thực

6
sự bắt đầu và dừng tiến trình bị ẩn đi trong lịch trình, mà thực sự là
khá nhỏ. Phần còn lại của hệ điều hành là độc đáo có cấu trúc trong
quá trình hình thành.
2.1.2 Thực hiện các tiến trình
Để thực hiện mô hình tiến trình, hệ điều hành duy trì một bảng (một
mảng của cấu trúc), được gọi là bảng tiến trình, với một mục nhập cho
mỗi tiến trình. Mục nhập này chứa thông tin về trạng thái quá trình, bộ
đếm chương trình của nó, con trỏ ngăn xếp, cấp phát bộ nhớ, tình trạng
của các tập tin mở, công tác kế toán và thông tin lịch trình, và mọi thứ
khác về tiến trình mà phải được lưu khi tiến trình bị chuyển từ chạy đến
chế độ sẵn sàng để nó có thể được khởi động lại sau, nếu như chưa bao
giờ được dừng lại.
Mặc dù các lĩnh vực chính xác có trong bảng tiến trình thay đổi từng hệ
thống một, nói chung một số sẽ đối phó với sự quản lý quá trình, số khác
với quản lý bộ nhớ, và vẫn còn những cái khác với hệ thống tập tin. Hình
2-4 cho thấy một số trong các lĩnh vực phổ biến hiện nay trong hệ thống
UNIX.
Bây giờ chúng ta đã xem xét quá trình bảng, có thể giải thích thêm
một chút về cách thức những ảo ảnh của nhiều quy trình tuần tự được duy
trì trên một máy tính với một CPU và thiết bị I/O. Kết hợp với mỗi I / O
cấp thiết bị (ví dụ, đĩa mềm, đĩa cứng, timre, thiết bị đầu cuối) là một vị
trí gần cuối của bộ nhớ được gọi là các vector ngắt. Nó chứa địa chỉ của
thủ tục dịch vụ ngắt. Giả sử người sử dụng quy trình 3 là chạy khi một đĩa
bị gián đoạn xảy ra. Chương trình truy cập, chương trình từ trạng thái, và
đăng ký có thể một hoặc nhiều hơn được đẩy lên ngăn xếp của các phần
cứng ngắt. Các máy tính sau đó nhảy đến địa chỉ ghi trong đĩa vector
ngắt. Đó là tất cả phần cứng nào. Từ đây trở đi, nó là đến phần mềm.
Các dịch vụ gián đoạn sản xuất bắt đầu bằng cách tiết kiệm tất cả các
đăng ký trong quá trình nhập bảng cho quá trình hiện hành. Số tiến trình

7
hiện tại và con trỏ đến mục nhập của nó được lưu giữ trong các biến toàn
cầu để họ có thể được tìm thấy nhanh chóng. Sau đó, các thông tin gửi
của các gián đoạn được lấy ra khỏi ngăn xếp và con trỏ ngăn xếp được
thiết lập để tạm thời ngăn xếp được sử dụng bởi quá trình xử lý. Hành
động như là tiết kiệm trong sổ đăng ký và đặt con trỏ ngăn xếp không thể
được thể hiện trong C (trên bất kỳ ngôn ngữ cấp cao khác) để họ được
thực hiện bởi một thói quen ngôn ngữ nhỏ lắp ráp. Khi thói quen này
xong, nó gọi một thủ tục C để làm các công việc thực tế của việc xử lý
ngắt.
Bước tiếp theo là xác định quá trình bắt đầu yêu cầu đĩa. Thông
thường tiến trình này sẽ phải đi vào chế độ nghỉ sau khi đã bắt đầu yêu
cầu, vì vậy bây giờ phải được đánh thức. Tình trạng của quá trình này
hiện đang thay đổi hình thức bị chặn để sẵn sàng và các lịch trình được
gọi là.
Cho dù tiến trình được chạy tiếp theo phụ thuộc vào các thuật toán lập
lịch biểu. Chúng tôi biết chắc chắn ít nhất là hai quá trình đã sẵn sàng tiến
trình đó bắt đầu các đĩa I / O và một trong những mà bị gián đoạn. Đó là
vào lịch trình để lựa chọn quan trọng nhất. Trong UNIX, ví dụ, một I / O
bị ràng buộc quá trình được ưu tiên cao hơn so với một quá trình liên kết
CPU, vì vậy nó có thể phát hành tiếp theo thiết bị I/O yêu cầu nhanh
chóng. Chiến lược này tối đa hóa số lượng song song, giữ cho cả hai đĩa
và CPU bận rộn. Tuy nhiên, hệ thống khác sử dụng phương án khác nhau,
ví dụ, nhấn mạnh sự công bằng hơn hiệu quả.
Để trở về quá trình vừa được chọn, các thủ tục C được gọi bởi mã lắp ráp
các gián đoạn ngôn ngữ bây giờ trở về, và lắp ráp mã tải ngôn ngữ lập sổ
đăng ký và bản đồ bộ nhớ cho quá trình hiện hiện tại và bắt đầu nó chạy.
Việc giao gián đoạn và lập lịch trình được tóm tắt trong hình 2-5.
1.Phần cứng ngăn xếp chương trình truy cập, vv.
2.Phần cứng mới tải chương trình truy cập từ vector ngắt

8
3.Ngôn ngữ hội thủ tục đăng ký lưu
4.Ngôn ngữ hội thủ tục thiết lập mới stack
5.C nhãn hiệu dịch vụ thủ tục quy trình như đã sẵn sàng
6.Scheduler quyết định mà quá trình chạy tiếp theo
7.C thủ tục trở về mã lắp ráp
8.Ngôn ngữ hội thủ tục khởi động quá trình hiện hành.
Hình 2-5: Bộ xương của những gì hệ điều hành nào khi gián đoạn xảy
ra

2.2 InterProcess Communication(truyền thông liên tiến trình)


Quy trình thường xuyên cần phải giao tiếp với các quá trình khác. Ví dụ,
trong một đường ống vỏ, sản lượng của quá trình đầu tiên phải được
chuyển đến các quá trình thứ hai, và như vậy sau này. Như vậy có một
nhu cầu giao tiếp giữa các quá trình, tốt hơn một cách có cấu trúc không
sử dụng ngắt. Trong các phần sau chúng tôi sẽ xem xét một số vấn đề liên
quan đến truyền thông này InterProcess hoặc IPC.
2.2.1 Điều kiện tranh đấu
Trong một số hệ thống hoạt động, quá trình đó đang làm việc với
nhau thường xuyên chia sẻ một số lưu trữ phổ biến mà mỗi người đọc và
viết. lưu trữ chia sẻ có thể là trong bộ nhớ chính hoặc nó có thể là một file
chia sẻ; các vị trí của các bộ nhớ chia sẻ không thay đổi bản chất của
truyền thông hoặc các vấn đề phát sinh. Để xem cách InterProcess khiển
công trình thực tế, chúng ta hãy xem xét một ví dụ đơn giản nhưng thông
thường, một spooler in. Khi một tiến trình muốn in một tập tin, nó đi vào
tên tập tin trong một thư mục spooler đặc biệt. Một quá trình, các daemon
máy in, định kỳ kiểm tra xem nếu có bất kỳ tập tin được máy in, và nếu
có nó in chúng và sau đó loại bỏ tên của họ từ các thư mục.

9
Hãy tưởng tượng rằng thư mục spooler của chúng tôi có một số (có khả
năng vô hạn) lớn của vùng, đánh số 0,1,2 .., từng có khả năng một trong
những tổ chức một tên file. Cũng tưởng tượng rằng có hai chia sẻ các
biến, trong, mà chỉ vào tập tin tiếp theo sẽ được in, và trong, mà chỉ vào
khe miễn phí tiếp theo trong thư mục. Hai biến cũng có thể được lưu giữ
trong một tập tin hai từ có sẵn để xử lý tất cả. Tại một tức nhất định, khe
0-3 là trống rỗng (các tập tin đã được in) và khe cắm 4-6 có đầy đủ (với
tên của tập tin xếp hàng đợi cho in ấn). Ít nhiều cùng một lúc, quá trình A
và B quyết định họ muốn xếp hàng một tập tin để in ấn. Tình trạng này là
hiển thị trong hình 2-6.
Trong khu vực pháp lý mà Murphy của pháp luật được áp dụng, để sau có
thể xảy ra. Tiến trình đọc vào và cửa hàng giá trị, 7, tại vị trí biến được
gọi là tiếp theo-miễn phí-khe. Chỉ sau đó một gián đoạn đồng hồ xảy ra
và CPU quyết định rằng quá trình A có đủ thời gian dài, do đó, nó chuyển
sang quá trình B. Quy trình B cũng đọc trong, và cũng có được một 7, do
đó các cửa hàng tên của tập tin trong khe 7 và cập nhật trong là một 8.
Sau đó, trong đi ra và làm những điều khác.
Cuối cùng quá trình A chạy một lần nữa, bắt đầu từ nơi nó rời đi. Có vẻ
ở bên cạnh khe cắm-miễn phí, phát hiện có 7 ở đó, và viết tên file của nó
trong khe 7, tẩy xoá tên mà quá trình B chỉ cần đặt ở đó. Sau đó máy tính
bên cạnh khe cắm-miễn phí + 1, mà là 8, và đặt trong đến 8. Các thư mục
spooler hiện trong nội bộ phù hợp, do đó, các nền máy in sẽ không nhận
thấy bất cứ điều gì sai, nhưng quá trình B sẽ không bao giờ nhận được bất
kỳ đầu ra. Tình huống như thế này, nơi mà hai hay nhiều quá trình đang
đọc hoặc viết một số dữ liệu được chia sẻ và kết quả cuối cùng phụ thuộc
vào người điều hành một cách chính xác khi nào, được gọi là điều kiện
chủng tộc. Debugging progarams có điều kiện chạy đua không có niềm
vui nào cả. Các kết quả của chạy vị nhất là tốt, nhưng một lần trong cuộc
đua, trong khi một cái gì đó kỳ lạ và không giải thích được xảy ra.

10
2.2.2 Phần chương trình tới hạn
Làm thế nào để chúng ta tránh các điều kiện chủng tộc? Chìa khóa để
ngăn ngừa sự cố ở đây và trong nhiều tình huống khác liên quan đến cổ
phần bộ nhớ, các tập tin chia sẻ, và chia sẻ mọi thứ khác, là tìm một số
cách để prohbit nhiều hơn một quá trình từ việc đọc và viết dữ liệu được
chia sẻ cùng một lúc. Đặt nói cách khác, những gì chúng ta cần là loại trừ
lẫn nhau-một số cách để đảm bảo rằng nếu một quá trình được sử dụng
một biến được chia sẻ hoặc tập tin, các quá trình khác sẽ được loại trừ
khỏi làm điều tương tự. Những khó khăn nêu trên xảy ra bởi vì quá trình
B bắt đầu sử dụng một trong các biến được chia sẻ trước khi quá trình A
được hoàn thành với nó. Sự lựa chọn của các hoạt động phù hợp nguyên
thủy để đạt được loại trừ lẫn nhau là một vấn đề thiết kế chính trong bất
kỳ hệ điều hành, và phải một mà chúng tôi sẽ xem xét một cách chi tiết
trong phần sau thứ.
Các vấn đề của cuộc đua tránh điều kiện cũng có thể được xây dựng theo
một cách trừu tượng. Một phần của thời gian, tiến trình được bận rộn tính
toán nội bộ và những thứ khác mà không dẫn đến điều kiện chủng tộc.
Tuy nhiên, đôi khi một quá trình của tôi được truy cập vào bộ nhớ chia sẻ
hoặc file, hoặc làm những việc khác quan trọng có thể dẫn đến các cuộc
đua. Đó là một phần của chương trình hợp bộ nhớ chia sẻ được truy cập
được gọi là phần quan trọng. Nếu chúng tôi có thể sắp xếp các vấn đề như
vậy mà không có hai quy trình đã bao giờ trong các phần quan trọng của
họ cùng một lúc, chúng ta có thể tránh điều kiện đua.
Mặc dù yêu cầu này tránh điều kiện chủng tộc, điều này là không đủ để
có quá trình song song hợp tác một cách chính xác và hiệu quả sử dụng
dữ liệu được chia sẻ. Chúng tôi cần bốn điều kiện để tổ chức để có một
giải pháp tốt:

11
1. Không có hai tiến trình có thể đồng thời bên trong bộ phận quan trọng
của họ.
2. Không có giả thiết có thể được thực hiện về tốc độ hoặc số của CPU.
3. Không có quá trình chạy ngoài phần quan trọng của nó có thể được
ngăn chặn các quá trình khác
4. Không có quy trình cần phải chờ đợi mãi mãi để nhập phần quan trọng
của nó.
2.2.3 Loại trừ lẫn nhau với Busy Waiting
Trong phần này chúng tôi sẽ xem xét các đề xuất khác nhau để đạt
được loại trừ lẫn nhau, do đó, trong khi một tiến trình đang bận cập nhật
bộ nhớ chia sẻ trong khu vực quan trọng của nó, không có tiến trình khác
sẽ vào rắc rối của mình quan trọng và gây ra.
Vô hiệu hóa ngắt
Các giải pháp đơn giản là có quá trình vô hiệu hóa tất cả mỗi ngắt ngay
sau khi enterting khu vực quan trọng của nó và tái anable họ chỉ trước khi
rời khỏi nó. Với ngắt tàn tật, không có gián đoạn đồng hồ có thể xảy ra.
CPU chỉ là chuyển từ quá trình xử lý như là kết quả của đồng hồ hoặc
gián đoạn, sau khi tất cả, và tắt ngắt CPU sẽ không được chuyển sang quá
trình khác. Vì vậy, một khi một quá trình đã bị vô hiệu hoá gây cản trở,
nó có thể kiểm tra và cập nhật bộ nhớ chia sẻ mà không lo sợ rằng bất kỳ
quá trình khác sẽ can thiệp.
Cách tiếp cận này thường không hấp dẫn vì nó là không khôn ngoan để
cho người dùng sức mạnh quá trình tắt ngắt. Giả sử một trong số họ đã
làm nó, và không bao giờ quay lại chúng trên một lần nữa? Điều đó có
thể là kết thúc của hệ thống. Hơn nữa, nếu máy tính đã cho hay CPU hơn,
vô hiệu hóa ngắt chỉ ảnh hưởng đến PU mà thực hiện các hướng dẫn vô
hiệu hóa. Những người khác sẽ tiếp tục chạy và có thể truy cập vào bộ
nhớ chia sẻ.

12
Mặt khác, nó thường thuận tiện cho hạt nhân chính nó để vô hiệu
hóa gián đoạn cho một vài hướng dẫn trong khi nó đang cập nhật biến
hoặc danh sách. Nếu một ngắt xảy ra trong khi danh sách của quá trình
chuẩn bị, ví dụ, đang ở trong một trạng thái không nhất quán, điều kiện
cuộc đua có thể xảy ra. Kết luận là: vô hiệu hóa ngắt đôi khi là một kỹ
thuật hữu ích trong hạt nhân, nhưng không thích hợp như là một cơ chế
loại trừ lẫn nhau cho các quy trình nói chung của người dùng.
Khóa các biến ( Lock variables)
Như là một nỗ lực thứ hai, chúng ta hãy tìm một giải pháp phần mềm.
Hãy xem xét việc có một, duy nhất ahared, (khóa) biến, ban đầu 0. Khi
một tiến trình muốn vào khu vực quan trọng của nó, đầu tiên nó kiểm tra
ổ khóa. Nếu khóa là 0, quá trình thiết lập nó thành 1 và đi vào khu vực
quan trọng. Nếu nhìn là đã 1, quá trình này chỉ muốn cho đến khi nó trở
thành 0.
Như vậy, một 0 có nghĩa là quá trình không có trong khu vực quan
trọng của nó, và 1 có nghĩa là quá trình một số là trong khu vực quan
trọng của nó.
Thật không may, ý tưởng này có chính xác cùng một lỗ hổng chết
người mà chúng ta đã thấy trong thư mục spooler. Giả sử một quá trình
đọc khóa và thấy rằng nó là 0. Trước khi nó có thể thiết lập các khóa 1,
một quá trình được lên kế hoạch chạy, và đặt ra các khóa để 1. Khi quá
trình đầu tiên chạy một lần nữa, nó cũng sẽ thiết lập các khóa 1, và hai
tiến trình sẽ được trong khu vực quan trọng của họ cùng một lúc.
Bây giờ bạn có thể nghĩ rằng chúng ta có thể có được xung quanh vấn
đề này bằng cách đọc đầu tiên ra giá trị khóa, sau đó kiểm tra lại một lần
nữa trước khi lưu trữ vào nó, nhưng đó thực sự không giúp được. Cuộc
đua bây giờ xảy ra nếu quá trình thứ hai sửa đổi các khóa ngay sau khi
quá trình đầu tiên đã hoàn tất kiểm tra thứ hai của mình.
Sự thay đổi chính xác (Strict Alternation)

13
Một cách tiếp cận thứ ba đối với vấn đề loại trừ lẫn nhau được thể hiện
trong hình 2-7. Đoạn chương trình này, như gần như tất cả các khác trong
cuốn sách này, được viết bằng C. Sự cạnh tranh là giữa C, Modula 2, và
Pascal. Mỗi đã ủng hộ và kẻ dèm pha của nó. C được chọn ở đây bởi vì
thực tế hệ điều hành thường được viết trong C, hiếm khi Modula 2, và
không bao giờ trong Pascal. Nếu bạn không quen với C, xin vui lòng đọc
phần giới thiệu nó tại Phụ lục B.
Trong hình 2-7, các biến số nguyên biến, ban đầu là 0, theo dõi những
người có biến nó là nhập khu vực quan trọng, kiểm tra hoặc cập nhật các
bộ nhớ chia sẻ. Ban đầu, quá trình 0 kiểm tra lại, thấy nó là 0, và đi vào
khu vực quan trọng của nó. Quy trình 1 cũng tìm thấy nó o là 0, và do đó
nằm trong một vòng lặp liên tục kiểm tra chặt chẽ biến để xem khi nào nó
sẽ trở thành 1.
Tiếp tục thử nghiệm một biến chờ đợi đối với một số giá trị để xuất hiện
được gọi là bận rộn đang chờ đợi. Nó thường nên tránh, vì nó lãng phí
thời gian của CPU. Chỉ khi có một kỳ vọng hợp lý rằng sự chờ đợi sẽ
được ngắn gọn là bận rộn đang chờ đợi được sử dụng.
Khi quá trình 0 lá phần quan trọng, nó thiết lập lần lượt là 1, để cho
phép quá trình 1 để nhập phần quan trọng của nó. Giả sử kết thúc quá
trình 1 phần quan trọng của nó nhanh chóng, do đó, cả hai quá trình nằm
trong phần không quan trọng của họ, với lần lượt thiết lập về 0. Trả giá
quá trình thực hiện vòng lặp 0 toàn bộ của nó một cách nhanh chóng, trở
lại với phần không quan trọng của nó với lần lượt thiết lập để 1. Tại thời
điểm này, quá trình 0 kết thúc phần không quan trọng của nó và đi trở lại
đầu của vòng lặp của nó. Rất tiếc là không được phép nhập phần quan
trọng của nó bây giờ, bởi vì lần lượt là 1 và quá trình 1 là bận rộn với
những phần không quan trọng của nó. Nói cách khác, thay phiên không
phải là một ý tưởng tốt khi một trong các quá trình chậm hơn nhiều so với
khác.

14
Tình hình này vi phạm điều kiện 3 nêu trên: quá trình 0 là bị chặn bởi
một quá trình không có trong phần quan trọng của nó. Quay trở lại thư
mục spooler thảo luận ở trên, nếu chúng ta kết hợp phần quan trọng với
việc đọc và viết các thư mục spooler, quá trình 0 sẽ không được phép để
in một tập tin bởi vì quá trình 1 là làm cái gì khác.
Trong thực tế, giải pháp này đòi hỏi rằng hai quy trình nghiêm ngặt
thay thế ở vào khu vực quan trọng của họ, ví dụ, trong spooling file.
Không một ai sẽ được phép spool hai liên tiếp. Trong khi thuật toán này
không tránh tất cả các chủng tộc, nó không thực sự là một ứng cử viên
nghiêm trọng như là một giải pháp.
Giải pháp của Peterson (Peterson's Solution)
Bằng cách kết hợp các ý tưởng nói chuyện lần lượt với ý tưởng của các
biến khóa và các biến cảnh báo. một nhà toán học Hà Lan, T. Dekker, là
người đầu tiên đưa ra một giải pháp phần mềm cho vấn đề loại trừ lẫn
nhau mà không cần thay đổi luân phiên nghiêm ngặt. Đối với một
discusion của thuật toán của Dekker, xem Dijkstra (1965).
Năm 1981, GL Peterson phát hiện ra một cách đơn giản hơn nhiều để
đạt được loại trừ lẫn nhau, do đó giải pháp dựng hình của Dekker lỗi thời.
Algotirithm Peterson là hình 2-8. Thuật toán này có hai thủ tục bằng văn
bản trong ANSI C, có nghĩa là nguyên mẫu chức năng nên được cung cấp
cho tất cả các chức năng định nghĩa và sử dụng. Thông thường, nguyên
mẫu đó được nhóm lại với nhau trong các tập tin header. Dòng đầu tiên
của hình 2-8 bao gồm tất cả các nguyên mẫu. Các chi tiết không thực sự
quan trọng ở đây, vì vậy họ không được liệt kê trong cuốn sách.
Trước khi sử dụng các biến được chia sẻ (ie.before vào đó khu vực
quan trọng), mỗi cuộc gọi quá trình sẽ gây ra nó để chờ đợi, nếu cần thiết,
cho đến khi nó là an toàn để vào. Sau khi nó đã hoàn tất với các biến
chung, các cuộc gọi quá trình rời khỏi vùng để cho biết rằng nó được thực
hiện và cho phép quá trình khác để nhập vào, nếu nó muốn thế.

15
Cho chúng tôi xem như thế nào giải pháp công trình này. Ban đầu quá
trình không phải là trong khu vực quan trọng. Trả quá trình 0 gọi nhập
vùng. Nó cho thấy sự quan tâm của mình bằng cách cài đặt phần tử mảng
của nó, và bộ chuyển sang 0. Kể từ khi quá trình 1 là không quan tâm,
hãy nhập vùng trả về ngay lập tức. Nếu quá trình 1 giờ gọi nhập khu vực,
nó sẽ treo ở đó cho đến khi quan tâm đến [0] đi đến FALSE, một sự kiện
chỉ xảy ra khi quá trình 0 gọi khu vực để lại.
Bây giờ xem xét các trường hợp đó cả hai quá trình gọi nter-khu vực
gần như cùng một lúc. Cả hai sẽ lưu trữ số của họ trong quá trình quay.
Cửa hàng dù được thực hiện cuối cùng là một trong những tính, là người
đầu tiên bị mất. Giả sử quá trình 1 cửa hàng mới nhất, do đó, lần lượt là
1. Khi cả hai quá trình đến với các tuyên bố trong khi đó, quá trình thực
thi nó không 0 lần, và đi vào khu vực quan trọng của nó. Quy trình 1
vòng lặp và không đi vào khu vực quan trọng của nó.
Các hướng dẫn TSL (The TSL instruction)
Bây giờ chúng ta xem xét một đề nghị mà yêu cầu sự giúp đỡ từ phần
cứng. Nhiều máy tính, đặc biệt là những thiết kế với nhiều bộ xử lý trong
tâm trí, có một chỉ dẫn TEST (TSL) mà các công trình như sau. Nó đọc
nội dung từ bộ nhớ vào một cửa hàng đăng ký và sau đó một giá trị khác
không tại địa chỉ bộ nhớ. Các hoạt động của việc đọc văn bản và lưu trữ
vào trong đó có bảo đảm là không chia-no vi xử lý khác có thể truy cập từ
cho đến khi lệnh được hoàn thành. CPU thực hiện các chỉ thị TSL khóa
bus bộ nhớ để ngăn cấm các CPU khác truy cập vào bộ nhớ cho đến khi
nó được thực hiện.
Để sử dụng hướng dẫn TSL, chúng tôi sẽ cho chúng ta một biến được
chia sẻ, cờ, để phối hợp truy cập vào bộ nhớ chia sẻ. Khi lá cờ là 0, bất kỳ
quá trình có thể thiết lập nó thành 1 bằng cách sử dụng các chỉ dẫn TSL
một sau đó đọc hay ghi bộ nhớ chia sẻ. Khi nó được thực hiện, xử lý các
bộ cờ lại là 0 bằng cách sử dụng một chỉ dẫn thường MOVE

16
Làm thế nào hướng dẫn này có thể được sử dụng để ngăn chặn hai quá
trình từ cùng một lúc vào khu vực quan trọng của họ? Giải pháp này được
đưa ra trong hình 2-9. Có bốn hướng dẫn chương trình con trong một
langgugae lắp ráp hư cấu (nhưng điển hình) được hiển thị. Các bản hướng
dẫn đầu tiên giá trị cũ của lá cờ để đăng ký và sau đó bộ cờ 1. Sau đó, các
giá trị cũ được so sánh với 0. Nếu đó là khác không, khóa đã được thiết
lập, do đó, chương trình chỉ cần đi lại cho các bài kiểm tra thứ hai bắt đầu
nó được. Sớm hay muộn nó sẽ trở thành 0 (khi quá trình hiện đang trong
phần quan trọng của nó được thực hiện với phần quan trọng của nó), và
trả về chương trình con, với các thiết lập khóa. Thanh toán bù trừ khóa
đơn giản. Chương trình chỉ các cửa hàng một 0 trong cờ. Không có chỉ
dẫn đặc biệt là cần thiết.

Một giải pháp cho vấn đề phần quan trọng bây giờ là đơn giản. Trước khi
vào phần quan trọng của nó, một quá trình gọi nhập khu vực, mà không
chờ đợi cho đến khi khóa bận rộn là tự do, sau đó nó mua lại các khóa và
trả về. Sau khi phần quan trọng tiến trình khu vực để kêu gọi, mà các cửa
hàng một 0 trong cờ. Như với tất cả các giải pháp dựa trên các khu vực
quan trọng, quá trình phải gọi nhập vùng và để lại vùng vào thời điểm
chính xác cho các phương pháp để làm việc. Nếu một quá trình gian lận,
loại trừ lẫn nhau sẽ thất bại.
2.2.4 Sleep và wakeup
Cả hai giải pháp của Peterson và các giải pháp sử dụng TSL là chính
xác, nhưng cả hai đều có những khiếm khuyết của các yêu cầu chờ đợi
bận rộn. Về bản chất, những gì các giải pháp này làm id này: khi một quá
trình muốn vào phần quan trọng của nó, nó sẽ kiểm tra xem mục nhập là
được cho phép. Nếu không, quá trình chỉ trong một vòng lặp kín chờ đợi
cho đến khi nó được.

17
Điều này không chỉ lãng phí thời gian tiếp cận CPU, nhưng nó cũng có
thể có tác dụng không mong muốn. Xem xét một máy tính với hai quá
trình, H, với ưu tiên cao và L, với ưu tiên thấp. Các quy tắc lập kế hoạch
là như vậy mà H là chạy bất cứ khi nào nó đang ở trong trạng thái sẵn
sàng. Tại một thời điểm nhất định, với L trong khu vực quan trọng của
nó, H trở nên sẵn sàng để chạy (ví dụ, một I / O hoạt động hoàn thành). H
bây giờ bắt đầu chờ đợi bận rộn, nhưng kể từ khi L là không bao giờ lên
kế hoạch trong khi H đang chạy, L không bao giờ nhận được thay đổi để
rời khỏi khu vực quan trọng của nó, do đó, H vòng mãi mãi. Tình hình
này đôi khi được gọi là vấn đề đảo ngược ưu tiên.

Bây giờ chúng ta xem xét một số nguyên thủy truyền thông InterProcess
rằng khối thay vì lãng phí thời gian CPU khi họ không được phép vào các
phần quan trọng của họ. Một trong những đơn giản nhất là các cặp
SLEEP và wakeup, giấc ngủ là một hệ thống gọi gây ra người gọi để
chặn, đó là, được treo cho đến khi quá trình khác đánh thức nó lên.
Các cuộc gọi wakeup có một tham số, quá trình sẽ được đánh thức.
Ngoài ra, cả hai SLEEP và wakeup từng có một tham số, một địa chỉ nhớ
được sử dụng để phù hợp với WAKEUPs SLEEP.

Vấn đề về nhà sản xuất - người tiêu dùng (The producer- consumer
Problem)
Như là một ví dụ về cách nguyên thủy này được sử dụng, chúng ta hãy
xem xét các vấn đề sản xuất-người tiêu dùng (còn gọi là vấn đề bộ đệm bị
chặn). Hai quá trình chia sẻ, thông thường cố định kích thước bộ đệm.
Một trong số đó, nhà sản xuất, đưa thông tin vào bộ đệm, và một trong
những khác, người tiêu dùng, có nó ra.
Rắc rối phát sinh khi sản xuất muốn đưa một mục mới trong bộ đệm,
nhưng nó đã được đầy đủ. Giải pháp là cho các nhà sản xuất để đi ngủ, để

18
được đánh thức khi người tiêu dùng đã loại bỏ một hoặc nhiều mục.
Tương tự, nếu người tiêu dùng muốn loại bỏ một otem từ uffer và thấy
rằng bộ đệm trống, nó đi vào giấc ngủ cho đến khi nhà sản xuất đặt một
cái gì đó trong bộ đệm và đánh thức nó lên.
Cách tiếp cận này có vẻ đơn giản, nhưng nó dẫn đến cùng loại của các
điều kiện chủng tộc chúng ta đã thấy các thư mục spooler. Để theo dõi
các số hạng mục trong bộ đệm, chúng tôi sẽ cần một biến, đếm. Nếu số
lượng tối đa của các bộ đệm có thể giữ được N, lạnh của nhà sản xuất đầu
tiên sẽ kiểm tra để xem nếu tính là N. Nếu có, các nhà sản xuất sẽ đi vào
giấc ngủ, nếu nó không phải là, nhà sản xuất sẽ thêm một mục và tăng
đếm.
Các mã của người tiêu dùng là tương tự: đếm thử nghiệm đầu tiên để
xem nếu là 0. Nếu có, đi ngủ, nếu nó có giá trị khác không, loại bỏ một
mục và giảm sự truy cập. Mỗi te quy trình cũng xét nghiệm để xem liệu
sự khác nên được ngủ, và nếu không, đánh thức nó lên. Các mã cho cả hai
nhà sản xuất và người tiêu dùng được thể hiện trong hình 2-10.

Để thể hiện các cuộc gọi hệ thống như SLEEP và wakeup trong C, chúng
tôi sẽ hiển thị chúng như các cuộc gọi đến thói quen thư viện. Họ không
phải là một phần của thư viện C chuẩn, nhưng có lẽ sẽ có trên các hệ
thống mà thực sự đã có các cuộc gọi hệ thống. Thủ tục nhập mục và loại
bỏ mục-, mà không được hiển thị, xử lý các sổ sách kế toán của việc đưa
các mục vào và các hạng mục trong bộ đệm.
Bây giờ chúng ta có thể trở về tình trạng chủng tộc. Nó có thể xảy ra
bởi vì truy cập vào tính là không bị giới hạn. Tình hình sau đây có thể có
thể xảy ra. bộ đệm rỗng và người tiêu dùng đã chỉ cần đọc số để xem nếu
nó là 0. Vào lúc đó, lịch trình các quyết định ngừng chạy cho người tiêu
dùng tạm thời và bắt đầu chạy các nhà sản xuất. Nhà sản xuất vào một
mục trong bộ đệm, số gia tăng, và thông báo rằng nó là bây giờ 1. Lý luận

19
rằng số lượng đã được chỉ là 0, và do đó người tiêu dùng phải được ngủ,
nhà sản xuất các cuộc gọi wakeup để đánh thức người tiêu dùng lên.
Thật không may, người tiêu dùng là chưa hợp lý trong giấc ngủ, do đó,
tín hiệu wakeup bị mất. Khi chạy của người tiêu dùng tới, nó sẽ kiểm tra
giá trị của số đó trước đây đã đọc. tìm thấy nó là 0, và đi ngủ. Sớm hay
muộn các nhà sản xuất sẽ điền vào bộ đệm và cũng đi ngủ. Cả hai sẽ ngủ
mãi mãi.
Bản chất của vấn đề ở đây là một wakeup gửi đến quá trình đó là
không (chưa) bị mất ngủ. Nếu không bị mất, mọi thứ sẽ được tất cả các
quyền. Một sửa chữa nhanh chóng là để sửa đổi các quy tắc để thêm một
wakeup chờ chút để hình ảnh. Khi wakeup được gửi đến một quá trình đã
được tỉnh táo, bit này được thiết lập. Sau này, khi quá trình cố gắng đi
ngủ, nếu chờ đợi wakeup bit được bật, nó sẽ được tắt, nhưng quá trình
này sẽ ở lại tỉnh táo. Các wakeup chờ đợi bit thực sự là một con heo đất
cho các tín hiệu wakeup
Chúng tôi, wakeup với ba bit lưu ngày ở đó một wakeup, nó rất dễ dàng
để xây dựng các ví dụ với ba hoặc nhiều hơn các quá trình trong đó một
wakeup chờ đợi bit là không đủ. Chúng ta có thể thực hiện một bản vá, và
thêm một chút wakeup thứ hai chờ đợi, hoặc có thể 8 hoặc 32 của họ,
nhưng về nguyên tắc vấn đề vẫn còn đó.

2.2.5 Các cờ hiệu/mã hiệu(semaphores)


đây là giải pháp trong năm 1965, khi EW Dijkstra (1965) đề nghị sử
dụng một biến số nguyên để đếm số wakeups lưu để sử dụng trong tương
lai. Trong đề xuất của ông, một loại biến mới, được gọi là semaphore, đã
được giới thiệu. Một semaphore có thể có giá trị 0, chỉ ra rằng không có
waeups được cứu sống, hoặc một số giá trị tích cực nếu một hoặc nhiều
wakeups đã chờ.
Dijkstra đề xuất có hai hoạt động, DOWN và UP (khái quát về giấc ngủ

20
và wakeup, respetively). Các hoạt động từ trên xuống trên một semaphore
kiểm tra để xem nếu giá trị lớn hơn 0. Nếu có, nó decrements giá trị (ví
dụ, sử dụng lên một wakeup lưu trữ) và chỉ continues.If giá trị là 0, quá
trình được đưa vào giấc ngủ. Cheking giá trị, thay đổi nó, và possibl đi
ngủ là tất cả được thực hiện như là một, một hành động chia nguyên tử,.
Nó được đảm bảo rằng một khi một hoạt động semphore đã bắt đầu,
không có tiến trình khác có thể truy cập các semaphore cho đến khi hoạt
động đã hoàn thành hoặc bị chặn. Số nguyên tử số này là hoàn toàn cần
thiết để giải quyết vấn đề đồng bộ và tránh điều kiện đua.
Hoạt động lên giá trị gia tăng của địa chỉ semaphore. Nếu một hoặc nhiều
tiến trình đang ngủ trên đó semaphore, không thể hoàn thành một hoạt
động xuống trước đó, một trong số họ được chọn bởi hệ thống (ví dụ, một
cách ngẫu nhiên), và được cho phép để hoàn thành xuống của nó. Như
vậy, sau khi UP trên một semaphone với quá trình ngủ trên đó, các
semaphone vẫn sẽ là 0, nhưng sẽ có một ít quá trình ngủ trên đó. Các hoạt
động của incrementing các semaphore và thức dậy một quá trình cũng
chia. Không bao giờ ngăn chặn quá trình làm một lên, giống như không
có tiến trình từng khối làm một wakeup trong mô hình trước đó.
Là một sang một bên, trong bài báo gốc Dijkstra, ông đã sử dụng tên P
và V thay vì DOWN và UP, tương ứng, nhưng từ những không có ý
nghĩa ghi nhớ cho những người không nói tiếng Hà Lan (và chỉ có biên ý
nghĩa cho những người làm), chúng tôi sẽ sử dụng các điều khoản
DOWN và UP thay thế. Những lần đầu tiên được giới thiệu trong Algol
68.
Giải quyết vấn đề sản xuất-người tiêu dùng bằng cách sử dụng
semaphore (Solving the Producer- Consumer Problem using
Semaphores)
Cờ hiệu điều phối giải quyết vấn đề mất-wakeup, như hình 2.11. Tôi là
điều cần thiết là họ được thực hiện theo một cách chia. Theo cách thông

21
thường là thực hiện UP và DOWN như các cuộc gọi hệ thống, với hệ điều
hành vô hiệu hoá tất cả gián đoạn một thời gian ngắn trong khi nó đang
thử nghiệm các semaphone, cập nhật tôi, và đưa quá trình ngủ, nếu cần
thiết. Như tất cả những hành động này chỉ mất một vài hướng dẫn, ham
không được thực hiện trong việc vô hiệu hóa ngắt. Nếu nhiều CPU đang
được sử dụng, mỗi semapone cần được bảo vệ bu một biến khóa, với các
chỉ dẫn TSL được sử dụng để đảm bảo rằng chỉ có một ngăn ngừa một số
CPU truy cập vào các semaphone đồng thời là khá khác nhau từ chờ đợi
bận rộn của nhà sản xuất hoặc người tiêu dùng chờ đợi cho các khác để
trống hoặc điền vào các bộ đệm. Các hoạt động semaphore sẽ chỉ mất
một vài micro giây, trong khi các nhà sản xuất hoặc người tiêu dùng có
thể mất tự ý kéo dài.
Giải pháp này sử dụng ba cờ tương ứng: một được gọi là đầy đủ để đếm
số lượng các khe cắm được đầy đủ, một gọi là trống rỗng, để đếm số
lượng các khe cắm đó là trống rỗng, và một mutex gọi là để đảm bảo sản
xuất và người tiêu dùng không truy cập vào bộ đệm tại cùng thời gian.
Toàn là ban đầu 0, trống rỗng ban đầu bằng số lượng khe n bộ đệm, và
mutex ban đầu 1. Semaphore được khởi tạo bằng 1 một bu sử dụng hai
hay nhiều quá trình để đảm bảo rằng chỉ một trong số họ có thể nhập vào
khu vực quan trọng của nó cùng một lúc được gọi là cờ hiệu điều phối
binay. Nếu từng có một quá trình xuống chỉ trước khi vào khu vực quan
trọng của nó và một lên chỉ sau khi rời khỏi nó, loại trừ lẫn nhau được
đảm bảo.

Bây giờ chúng ta có một truyền InterProcess tốt nguyên thủy tại xử lý của
chúng tôi để chúng tôi quay trở lại và nhìn vào sequnce gián đoạn của Fif
2,5 lần nữa. Một hệ thống sử dụng cờ hiệu điều phối một cách tự nhiên để
ẩn ngắt là phải có một semaphore, ban đầu thiết lập về 0, kết hợp với mỗi
thiết bị I / O. Chỉ sau khi nhìn chằm chằm một I / O thiết bị, quy trình

22
quản lý hiện một DOWN trên semaphore liên quan, do đó ngăn chặn
ngay lập tức. Khi gián đoạn đến, quá trình có liên quan đã sẵn sàng để
chạy lại. Trong mô hình này, bước 5 hình 2,5 bao gồm làm một UP trên
semaphore của thiết bị, để trong bước 6 bây giờ đã sẵn sàng, các lịch trình
sẽ có thể chạy các quản lý thiết bị. Tất nhiên, nếu một số máy ép đã sẵn
sàng, các lịch trình có thể chọn để chạy một quá trình quan trọng hơn tiếp
theo. Chúng tôi sẽ xem xét cách lập lịch trình được thực hiện sau đó trong
chương này.
Trong ví dụ của hình 2,11, chúng tôi đã thực sự được sử dụng
samaphores theo hai cách khác nhau. khác nhau này là quan trọng đủ để
làm cho rõ ràng. Mutex Các semaphore được sử dụng để loại trừ lẫn
nhau. Nó được thiết kế để đảm bảo rằng chỉ có một quy trình tại một thời
điểm sẽ được đọc hoặc viết bộ đệm và các biến liên quan. Điều này loại
trừ lẫn nhau là cần thiết để ngăn chặn tình trạng hỗn loạn.
Việc sử dụng khác của semaphore được cho đồng bộ hóa. Các cờ hiệu
điều phối đầy đủ và có sản phẩm nào là cần thiết để đảm bảo rằng chuỗi
sự kiện nào đó làm hoặc không xảy ra. Trong trường hợp này, họ đảm
bảo rằng các nhà sản xuất ngừng chạy khi bộ đệm đầy, và người tiêu
dùng sẽ ngừng chạy khi nó được sản phẩm nào. Việc sử dụng này là khác
nhau từ loại trừ lẫn nhau.

Các giải pháp cho vấn đề sản xuất-người tiêu dùng bằng cách sử dụng cờ
hiệu điều phối dựa vào loại trừ lẫn nhau để tránh điều kiện đua. Trong
phần này chúng tôi sẽ mô tả như một phương pháp. Nó sử dụng một loại
đặc biệt của biến được gọi là truy cập sự kiện (Reed và Kanodia, 1979).
Ba hoạt động được định nghĩa về một sự kiện điện tử truy cập:
1. Đọc (E): Trả lại giá trị hiện tại của E
2. Advance (E): E nguyên tử tăng lên 1

23
3. Chờ đợi (E, v): chờ đợi cho đến khi E có giá trị của v hoặc nhiều
hơn.
Vấn đề sản xuất-người tiêu dùng không sử dụng đọc, nhưng nó là cần
thiết cho các vấn đề đồng bộ hóa khác.
Chú ý rằng sự kiện truy cập chỉ tăng, không bao giờ qua đời. Họ luôn
luôn bắt đầu từ 0. Hình 2,12 cho thấy vấn đề sản xuất-người tiêu dùng
một lần nữa, lần này sử dụng bộ đếm sự kiện.
Hai bộ đếm sự kiện được sử dụng. Việc đầu tiên, trong, đếm số tích lũy
các khoản mục có nhà sản xuất đã đưa vào bộ đệm từ các chương trình
bắt đầu chạy. Một trong những khác, ra, đếm số tích lũy của các mục mà
người tiêu dùng đã xoá khỏi bộ đệm cho đến nay. Tôi rõ ràng là trong
phải lớn hơn hoặc bằng ra, nhưng không phải bởi nhiều hơn kích thước
của bộ đệm.
Khi sản xuất có máy tính một mục mới, nó sẽ kiểm tra để xem nếu có
roomin bộ đệm, sử dụng hệ thống đang chờ đợi. Ban đầu, trên khái là 0
và trình tự-N sẽ được tiêu cực, do đó, poducer không chặn. Nếu nhà sản
xuất tạo ra N +1 các mục trước khi người tiêu dùng đã bugun, tuyên bố sẽ
chờ đợi cho đến khi ra trở thành 1, một cái gì đó sẽ chỉ xảy ra sau khi
người tiêu dùng đã loại bỏ một mục.
Logic của người tiêu dùng thậm chí còn đơn giản hơn. Trước khi cố
gắng để loại bỏ các mục k-ngày, nó chỉ cần chờ đợi cho đến khi trong đã
đạt đến k, đó là, ngày sản xuất đã đặt mục k vào bộ đệm

2.2.7 Màn hình(Monitor)


Với cờ hiệu và quầy sự kiện, truyền thông InterProcess vẻ dễ dàng,
phải không? Kệ nó. Nhìn kỹ vào thứ tự của các thăng trầm trước khi vào
hoặc loại bỏ các mục khỏi bộ đệm trong hình 2.11. Giả sử hai thăng trầm
trong mã của nhà sản xuất đã được đảo ngược để, do đó, mutex được
giảm đi trước khi có sản phẩm nào thay vì sau đó. nếu bộ đệm đã được

24
hoàn toàn đầy đủ, nhà sản xuất sẽ block, với mutex đặt. Do đó, trong thời
gian tới người tiêu dùng cố gắng truy cập vào bộ đệm, nó sẽ làm một
DOWN trên mutex, bây giờ 0, và ngăn chặn quá. Cả hai quá trình sẽ ở lại
mãi mãi bị khóa và không làm việc nhiều hơn bao giờ hết sẽ được thực
hiện. Tình trạng này không may mắn được gọi là bế tắc. Chúng tôi sẽ
nghiên cứu cụ thể khóa chết trong chap 6

Vấn đề này là chỉ ra cho thấy làm thế nào bạn phải cẩn thận khi sử dụng
semapphores. Một tinh tế lỗi và tất cả mọi thứ đi kèm như đã chấm dứt.
Nó giống như lập trình bằng ngôn ngữ lắp ráp, chỉ tồi tệ hơn, bởi vì các
lỗi là điều kiện chủng tộc, khóa chết, và các hình thức khác về hành vi
không thể đoán trước và irrerproducible.
Để làm cho nó dễ dàng hơn để viết chương trình chính xác, Hoare
(1974) và Brinch Hansen (1975) đề xuất một đồng bộ hóa cao hơn đòn
bẩy nguyên thủy được gọi là một màn hình. Đề xuất của họ khác nhau
một chút, như mô tả dưới đây. Một monitoris một bộ sưu tập các thủ tục,
biến và các cấu trúc dữ liệu đó là tất cả các nhóm lại với nhau trong một
dạng đặc biệt của mô-đun hoặc gói. Quy trình có thể gọi được các thủ tục
trong một màn hình bất cứ khi nào họ muốn, nhưng họ không thể trực
tiếp truy cập vào cấu trúc dữ liệu nội bộ của thủ tục khai báo theo dõi từ
bên ngoài màn hình. Hình minh họa một màn hình 2,13 được viết bằng
một ngôn ngữ tưởng tượng, bồi Pascal

Màn hình có một tài sản quan trọng là làm cho chúng hữu ích để đạt được
loại trừ lẫn nhau: Chỉ có một quá trình có thể được hoạt động trong một
màn hình ở ngay lập tức bất kỳ. Monitor là một ngôn ngữ lập trình xây
dựng, do đó, trình biên dịch biết họ là đặc biệt và có thể xử lý cuộc gọi để
theo dõi các thủ tục khác nhau từ các thủ tục các cuộc gọi thông thường,
khi xử lý một cuộc gọi một thủ tục theo dõi, hướng dẫn thủ tục đầu tiên sẽ

25
kiểm tra xem nếu có khác quá trình đang hoạt động trong màn hình. Nếu
vậy, quá trình gọi sẽ bị đình chỉ cho đến khi quá trình khác có trái màn
hình. Nếu không có tiến trình khác đang sử dụng màn hình, quá trình gọi
điện thoại có thể nhập.
Đó là vào các trình biên dịch để thực hiện loại trừ lẫn nhau về các mục
theo dõi, nhưng là một cách phổ biến là sử dụng một semaphore nhị phân.
Bởi vì các trình biên dịch, không phải là lập trình, được bố trí cho các loại
trừ lẫn nhau, rất ít khả năng là một cái gì đó sẽ đi sai. Trong mọi trường
hợp, người có văn bản cho màn hình không phải được nhận thức của trình
biên dịch như thế nào sắp xếp để loại trừ lẫn nhau. Nó đủ để làm thế nào
mà bằng cách chuyển tất cả các phần quan trọng vào các thủ tục theo dõi,
không có hai quá trình khái bao giờ thực hiện phần quan trọng của họ
cùng một lúc.

Mặc dù màn hình cung cấp một cách dễ dàng để đạt được loại trừ lẫn
nhau, như chúng ta đã thấy ở trên, đó là không đủ. chúng ta cũng cần một
cách để các quy trình để chặn khi họ không thể tiến hành. Trong vấn đề
sản xuất-người tiêu dùng, nó rất dễ dàng, đủ để đặt tất cả các xét nghiệm
cho toàn bộ đệm và bộ đệm trống trong các thủ tục theo dõi, nhưng làm
thế nào nên các khối sản xuất khi nó tìm thấy bộ đệm đầy đủ?
Giải pháp này nằm trong phần giới thiệu của các biến điều kiện, cùng với
hai hoạt động trên chúng, WAT và tín hiệu. Khi một thủ tục giám sát phát
hiện ra rằng nó không thể tiếp tục (ví dụ, nhà sản xuất thấy bộ đệm đầy
đủ), nó có một WAT trên một số biến điều kiện, nói, đầy đủ. Hành động
này gây ra quá trình gọi điện thoại để chặn. Nó cũng cho phép một quá
trình đã được trước đó bị cấm vào màn hình để vào ngay.
Quá trình này khác, ví dụ, người tiêu dùng, có thể thức giấc ngủ của đối
tác bằng cách thực hiện một tín hiệu trên, ông biến điều kiện là đối tác
của mình là chờ đợi. Để tránh có hai quá trình hoạt động trong màn hình

26
cùng một lúc, chúng ta cần một quy tắc nói những gì xảy ra sau khi một
tín hiệu. Hoare đề nghị nên để quá trình mới được đánh thức, đình chỉ
một khác. Brinch Hanse đề xuất finessing vấn đề bằng cách yêu cầu mà
một quá trình làm một tín hiệu phải thoát khỏi màn hình ngay lập tức. Nói
cách khác, một tuyên bố tín hiệu có thể xuất hiện chỉ như là báo cáo cuối
cùng trong một thủ tục theo dõi. Chúng tôi sẽ sử dụng đề nghị của
Hansen Brinch bởi vì đó là khái niệm đơn giản hơn và tôi cũng dễ dàng
hơn để thực hiện. Nếu một tín hiệu được thực hiện trên một biến điều
kiện mà một số quy trình được chờ đợi, chỉ một trong số đó, xác định bởi
hệ thống lập lịch, được hồi sinh.

Các biến điều kiện không phải là những bộ đếm. Chúng không tích lũy
các tín hiệu để sử dụng sau cách mà các mã hiệu làm. Vì vậy, nếu một
biến điều kiện là báo hiệu không có một chờ đợi trên đó, tín hiệu sẽ bị
mất. Các WAIT phải đến trước khi các quy tắc SIGNAL.This làm cho
việc thực hiện đơn giản hơn nhiều. Trong thực tế nó không phải là một
vấn đề bởi vì nó rất dễ dàng để theo dõi trạng thái của mỗi quá trình với
các biến, nếu cần thiết. Một quá trình mà nếu không có thể làm một tín
hiệu có thể thấy rằng hoạt động này là không cần thiết bằng cách nhìn
vào các biến.
Một bộ xương của vấn đề sản xuất-người tiêu dùng với màn hình được
đưa ra trong hình 2,14 trong bồi Pascal.
Bạn có thể nghĩ rằng các hoạt động WAT và tín hiệu trông giống như
giấc ngủ và wakeup, mà chúng ta đã thấy có điều kiện chủng tộc gây tử
vong. Họ rất tương tự, nhưng với sự khác biệt quan trọng nhất: SLEEP và
wakeup không thành công bởi vì trong khi một quá trình đã cố gắng để đi
vào giấc ngủ, người khác đã cố gắng để đánh thức nó dậy. Với màn hình,
mà không thể xảy ra. Tự động loại trừ lẫn nhau về đảm bảo sản xuất màn
hình rằng nếu, nói rằng, nhà sản xuất bên trong một thủ tục giám sát phát

27
hiện ra rằng bộ đệm đầy, nó bility mà bộ lịch trình có thể chuyển đổi cho
người tiêu dùng chỉ cần trước khi WAT hoàn tất. Người tiêu dùng sẽ
không được phép vào theo dõi ở tất cả cho đến khi WAT kết thúc và nhà
sản xuất đã được đánh dấu là không còn Runnable.
Bằng cách làm cho loại trừ lẫn nhau của các vùng trọng tự động, màn
hình lập trình song song làm cho ít hơn nhiều dễ bị lỗi hơn so với
semaphore, Tuy nhiên, họ cũng có một số nhược điểm. Nó không phải là
cho không có gì mà hình 2.14, được viết bằng một loại kỳ lạ của Pascal
bồi hơn là trong C, như là những ví dụ khác trong sách này. Như chúng ta
đã nói trước đó, theo dõi là một ngôn ngữ lập trình khái niệm. Trình biên
dịch phải công nhận họ và sắp xếp việc loại trừ lẫn nhau bằng cách nào
đó. C, pscal và hầu hết các ngôn ngữ khác không có màn hình, vì vậy nó
là không hợp lý để mong đợi các trình biên dịch của họ để thực thi các
quy tắc loại trừ bất kỳ lẫn nhau. Trong thực tế, làm thế nào có thể trình
biên dịch biết các thủ tục ở trong màn hình và có được không?

Những ngôn ngữ không có cờ hiệu, hoặc, nhưng thêm cờ tương ứng là dễ
dàng: Tất cả bạn cần làm là thêm hai ngôn ngữ ngắn assemply thói quen
đến thư viện để vấn đề này UP và các cuộc gọi hệ thống từ trên xuống.
Các trình biên dịch không có sự kiện để biết rằng chúng tồn tại. Tất
nhiên, các hệ điều hành phải biết về hệ điều hành dựa trên semaphore,
bạn có thể viết các chương trình sử dụng để nó trong C hoặc Pascal hoặc
thậm chí cơ bản nếu bạn đang masochistic đủ. Với màn hình, bạn cần một
ngôn ngữ có họ xây dựng in Một vài ngôn ngữ, chẳng hạn như đồng thời
Euclid (Holt, 1983) có họ, nhưng họ là rất hiếm.
Một vấn đề với màn hình, và cũng với semaphore, là chúng được thiết
kế để giải quyết các vấn đề loại trừ lẫn nhau trên một hoặc nhiều (hoặc sự
kiện đếm) trong bộ nhớ chia sẻ và bảo vệ chúng với các hướng dẫn TSL,
chúng ta có thể tránh các cuộc đua. Khi chúng tôi đi đến một hệ thống

28
phân phối gồm nhiều CPU, mỗi bộ nhớ tin của riêng mình, kết nối bởi
một mạng cục bộ, các nguyên thủy trở thành không áp dụng. Kết luận là
cờ hiệu điều phối cấp quá thấp và màn hình không thể sử dụng được
ngoại trừ trong một vài ngôn ngữ lập trình. Hơn nữa, không có nguyên
thủy cung cấp cho việc trao đổi thông tin giữa các máy. Cái gì khác là cần
thiết.
2.2.8 sự chuyển thông báo ( Message Passing)
Một cái gì đó khác là sự chuyển thông báo. Phương pháp
truyền thông liên tiến trình sử dụng hai nguyên hàm gửi và tiếp nhận,
trong đó,. như cờ hiệu điều phối một không giống như màn hình, là hệ
thống các cuộc gọi hơn là cấu trúc ngôn ngữ. Như vậy, họ có thể dễ dàng
được đưa
vào các thủ tục thư viện, chẳng hạn như
Điều thứ nhất gửi một thông điệp đến một đích nhất định và sau đó
nhận được một tin nhắn từ một nguồn cụ thể (hoặc từ bất kỳ, nếu người
nhận không quan tâm). Nếu tin nhắn không có sẵn, người nhận có thể
ngăn chặn cho đến khi một đến.
Những vấn đề thiết kế cho các hệ thống chuyển thông báo
Hệ thống chuyển thông báo có nhiều vấn đề thách thức và các vấn đề
thiết kế mà không phát sinh với cờ hiệu điều phối hoặc theo dõi đặc biệt
là nếu các quá trình giao tiếp được trên các máy khác nhau được kết nối
bởi mạng. Ví dụ, tin nhắn có thể bị mất do mạng. Để bảo vệ chống lại tin
nhắn bị mất, người gửi và Đầu giải mã truyền có thể đồng ý rằng ngay
khi một ha tin nhắn được nhận, người nhận sẽ gửi lại tin nhắn xác nhận
đặc biệt. Nếu người gửi đã không nhận được sự thừa nhận trong một
khoảng thời gian nhất định nếu phát lại tin nhắn.
Bây giờ xem xét những gì sẽ xảy ra nếu các thông điệp của bạn nhận
được một cách chính xác, nhưng xác nhận là bị mất. Người gửi sẽ truyền
lại thông điệp, do đó, người nhận sẽ nhận được nó hai lần. Điều cần thiết

29
là người nhận có thể phân biệt một tin nhắn mới từ việc phát lại của một
cũ. Thông thường vấn đề này được giải quyết bằng cách đặt số thứ tự liên
tiếp ở mỗi tin ban đầu, nó biết rằng thông điệp là bản sao mà một bị bỏ
qua.
Thông báo hệ thống cũng phải đối phó với các câu hỏi của quá trình
được đặt tên như thế nào, để quá trình quy định tại một cuộc gọi gửi oe
tiếp nhận được rõ ràng. Thường một chương trình đặt tên như máy @ quá
trình hay máy: quá trình được sử dụng
Nếu số lượng máy là rất lớn, và không có cơ quan trung ương cấp phát
tên máy, có thể xảy ra là hai tổ chức cung cấp cho máy tính của họ cùng
tên. Các vấn đề của các cuộc xung đột có thể được giảm considerrably
bằng cách nhóm các máy vào các lĩnh vực và sau đó giải quyết các quá
trình như process@machine.domain. Trong sơ đồ này không có vấn đề to
nếu hai máy có cùng tên, với điều kiện là họ đang có trong tên miền khác
nhau. các tên miền cũng phải là duy nhất, tất nhiên.
Chứng thực cũng là một vấn đề trong các hệ thống tin nhắn: Làm thế
nào có thể được khách hàng nói rằng ông là giao tiếp với các máy chủ
thực sự, và không có kẻ lường gạt? Làm thế nào các máy chủ tập tin có
thể nói cho mà khách hàng đã yêu cầu một tập tin? Mã hóa tin nhắn với
một phím duy nhất để người dùng biết được uỷ quyền thường có thể hữu
ích ở đây.
Ở đầu kia của quang phổ, cũng có thiết kế vấn đề quan trọng khi người
gửi và người nhận là trên cùng một máy. Một trong số này là hiệu suất.
Sao chép tin nhắn từ một quá trình khác là luôn luôn chậm hơn so với
thực hiện một hoạt động semaphore, nhập cảnh một màn hình. Phần lớn
công việc đã đi vào làm cho tin nhắn qua hiệu quả. Cheriton (1984), ví
dụ, đã đề xuất hạn chế kích thước thông báo cho những gì sẽ phù hợp
trong regiters của máy, và sau đó làm thông qua việc sử dụng sổ đăng ký.

30
Vấn đề sản xuất-người tiêu dùng với sự chuyển thông điệp (The
producer-Consumer Problem with message Passing)
Bây giờ chúng ta xem cách các vấn đề sản xuất-người tiêu dùng có
thể được giải quyết với truyền thông và bộ nhớ không được chia sẻ. Một
giải pháp được đưa ra trong hình 2.15. chúng tôi giả định rằng tất cả các
tin nhắn có cùng kích thước và tin nhắn đã gửi nhưng chưa nhận được
đệm tự động bởi hệ điều hành. Trong giải pháp này, tổng số N tin được
sử dụng, tương tự như các khe cắm N trong một bộ nhớ đệm chia sẻ.
Người tiêu dùng bắt đầu ra bằng cách gửi tin nhắn N trống để sản xuất.
Bất cứ khi nào nhà sản xuất có một mục để cung cấp cho người tiêu dùng,
phải mất một tin nhắn empy và gửi lại một một đầy đủ. Bằng cách này,
tổng số tin nhắn trong hệ thống vẫn liên tục trong thời gian, để họ có thể
được lưu trữ trong một lượng bộ nhớ.
Nếu sản xuất các công trình nhanh hơn so với người tiêu dùng, tất cả
các tin nhắn sẽ kết thúc đầy đủ. chờ đợi cho người tiêu dùng, nhà sản xuất
sẽ bị chặn, chờ đợi cho một sản phẩm nào để trở lại. Nếu người tiêu dùng
hoạt động nhanh hơn, sau đó đảo ngược sẽ xảy ra: tất cả các tin nhắn sẽ
được đổ chờ đợi cho sản xuất để điền vào chúng: người tiêu dùng sẽ bị
chặn chờ đợi một tin nhắn đầy đủ.
Nhiều biến thể có thể với qua tin nhắn. Để bắt đầu, hãy cho chúng tôi
xem tin nhắn ho được giải quyết. Một cách là mỗi quá trình chỉ định một
địa chỉ duy nhất và có tin nhắn được gửi đến các quá trình. Một cách khác
là phát minh ra một cấu trúc dữ liệu mới, được gọi là hộp thư. Hộp thư là
một nơi để đệm một số lượng nhất định của tin nhắn, thông thường quy
định khi hộp thư được tạo ra. Khi hộp thư được sử dụng, các thông số địa
chỉ trong các cuộc gọi gửi và tiếp nhận được hộp thư, không phải quá
trình. Khi một tiến trình tris để gửi đến một hộp thư đầy, nó được treo cho
đến khi thông điệp được lấy ra từ hộp thư đó.

31
Đối với vấn đề sản xuất-người tiêu dùng, cả hai nhà sản xuất và người
tiêu dùng sẽ tạo ra các hộp thư đủ lớn để chứa N tin. Các nhà sản xuất sẽ
gửi tin nhắn có chứa dữ liệu đến hộp thư của người tiêu dùng, và người
tiêu dùng sẽ gửi tin nhắn trống đến hộp thư của nhà sản xuất. Khi hộp thư
được sử dụng, cơ chế đệm là rõ ràng: Các hộp thư đích thông báo giữ đã
được gửi đến các quá trình địa điểm nhưng chưa được chấp nhận.
Những thái cực khác từ việc có hộp thư là loại bỏ tất cả đệm. Khi
phương pháp này là tiếp theo, nếu gửi được thực hiện trước khi tiếp nhận,
quá trình gửi bị chặn cho đến khi tiếp nhận các xảy ra, vào thời điểm đó
tin này có thể được sao chép trực tiếp từ người gửi đến người nhận,
không có đệm trung gian. Tương tự như vậy, nếu thường được biết đến
như một điểm hẹn. Nó là dễ dàng hơn để thực hiện hơn là một chương
trình tin nhắn đệm nhưng ít linh hoạt hơn kể từ khi người gửi và người
nhận buộc phải chạy theo và bước.
Các thông tin liên lạc InterProcess giữa tiến trình người dùng trong
UNIX là thông qua đường ống đó là hộp thư có hiệu quả. Chỉ có thực sự
khác nhau giữa một hệ thống tin nhắn với các hộp thư và cơ chế đường
ống là ống không giữ giới tin. Nói cách khác, nếu một quá trình viết 10
tin nhắn là 100 byte cho một đường ống và các quá trình khác đọc 100
byte từ đường ống đó, người đọc sẽ nhận được tất cả 10 tin nhắn cùng
một lúc. Với một hệ thống tin nhắn thật, mỗi ĐỌC nên trở lại chỉ có một.
tin nhắn. Tất nhiên, nếu các quá trình đồng ý để đọc và ghi kích thước cố
định tin nhắn từ ống, hoặc để kết thúc mỗi tin nhắn với một nhân vật đặc
biệt (ví dụ, đường thức ăn), không có vấn đề phát sinh.

2.2.9 tương đương của các nguyên hàm (Equivalence of Primtives)


Reed và Kanodia (1979) mô tả một phương pháp giao tiếp
InterProcess khác nhau gọi là sequencers. Campbell và Habermamn (974)
thảo luận một phương pháp được gọi là biểu thức đường dẫn. Atkinsn và

32
Hewitt (1979) serializers giới thiệu. Trong khi danh sách các phương
pháp khác nhau không phải là vô tận, nó chắc chắn là khá dài, với những
người mới được mơ ước lên tất cả các thời gian. May mắn thay, nhiều đề
án đề xuất tương tự như những người khác.
Trong phần trước chúng tôi đã nghiên cứu bốn nguyên thủy
InterProcess truyền thông khác nhau. Hơn họ năm, mỗi một người ủng hộ
đã tích lũy cho rằng cách ưa thích của ngươi là cách tốt nhất. Sự thật của
vấn đề là tất cả những phương pháp cơ bản là ngữ nghĩa tương đương (ít
nhất là như xa như các hệ thống CPU duy nhất có liên quan). Sử dụng bất
kỳ trong số đó bạn có thể xây dựng những người khác
Chúng tôi bây giờ sẽ hiển thị tương đương thiết yếu của cờ hiệu điều
phối, giám sát, và thông điệp. Đây không chỉ là thú vị ở bên phải của
riêng của nó, nhưng nó cũng cung cấp cái nhìn sâu sắc hơn và hiểu biết
về cách thức nguyên thủy làm việc và làm thế nào họ có thể được thực
hiện. Thiếu không gian ngăn cản chúng tôi hình thức xử lý với quầy sự
kiện là tốt, nhưng cách tiếp cận chung phải rõ ràng từ các ví dụ khác.
Sử dụng các cờ hiệu để Thực hiện các bộ điều chỉnh và tin nhắn
(Using semaphores to Implement Monitors and message)
Hãy để chúng tôi đầu tiên xem như thế nào chúng ta có thể xây dựng
màn hình và semaohores tin nhắn sử dụng. Nếu hệ điều hành cung cấp cờ
tương ứng như là một nhà văn anycompiler cơ bản, có thể dễ dàng thực
hiện giám sát trong ngôn ngữ của mình như sau. Lần đầu tiên một bộ sưu
tập thời gian chạy nhỏ của thủ tục giám sát quản lý được xây dựng và đưa
vào thư viện. Đây là những liệt kê trong hình 2.16. Sau đó, bất cứ khi nào
tạo mã liên quan đến giám sát, các cuộc gọi được thực hiện cho các thủ
tục thời gian chạy thích hợp để thực hiện chức năng cần thiết.
Kết hợp với từng màn hình là một semaphore nhị phân, ban đầu 0, để
kiểm soát nhập cảnh vào màn hình, và semaphore bổ sung, ban đầu là 0,
mỗi biến điều kiện. Khi quá trình nhập vào một màn hình, trình biên dịch

33
tạo ra một cuộc gọi đến theo dõi thời gian chạy thủ tục nhập, mà không
một DOWN trên mutex kết hợp với màn hình được nhập vào. Nếu màn
hình hiện đang sử dụng, quá trình sẽ chặn.
Mặc dù nó có vẻ hợp lý rằng mã cho thoát ra một màn hình đơn giản
làm một UP trên mutex, giải pháp đơn giản này không luôn luôn làm
việc. Khi quá trình không báo hiệu bất kỳ quá trình khác, sau đó nó có
thể, quả thật vậy, chỉ cần UP mutex và thoát khỏi màn hình. Trường hợp
này được hiển thị như bình thường để lại, trong hình 2,16.
Biến chứng này xuất phát từ các biến điều kiện. WAIT trên một biến
điều kiện, c, được thực hiện như là một chuỗi của hai hoạt động
semphore. Đầu tiên có một UP trên mutex, để cho phép các quá trình
khác để vào màn hình. Rồi có một DOWN trên c chặn trên biến điều
kiện.
Hãy nhớ rằng tín hiệu luôn luôn phải được thực hiện như hoạt động
cuối cùng trước khi rời khỏi một màn hình. Quy luật này là cần thiết để
có thể kết hợp tín hiệu và thoát ra thành các thủ tục thư viện để lại-với-tín
hiệu. Tất cả nó một UP biến điều kiện. Sau đó nó rời khỏi màn hình mà
không phát hành mutex. Bí quyết ở đây là kể từ khi mutex vẫn 0, không
có tiến trình khác có thể nhập vào màn hình, và sẽ làm một UP trên
mutex khi lá. Theo cách này, quá trình truyền tín hiệu truyền có hiệu quả
loại trừ lẫn nhau cho quá trình phát tín hiệu để đảm bảo không có đối thủ
cạnh tranh có được nó.
Bây giờ chúng ta thấy cơ chế này hoạt động với các vấn đề sản xuất-
người tiêu dùng. Các semaphore mutex đảm bảo rằng mỗi quá trình có
thể truy cập độc quyền cho các giám sát cho phần quan trọng của nó. Giả
sử người tiêu dùng bắt đầu đầu tiên và phát hiện ra rằng không có làm
việc cho nó vào bộ đệm. Nó không một WAIT trống rỗng, mà nguyên
nhân một UP mutex và một DOWN về sản phẩm nào. Người tiêu dùng đi
vào giấc ngủ, và sản xuất được phép vào ngay khi nó muốn. Khi sản xuất

34
phát hiện ra rằng tính (xem hình 2.14) là 1, nó sẽ làm tín hiệu trống để
đánh thức người tiêu dùng. Tại thời điểm này cả hai prodecer và người
tiêu dùng đang hoạt động trong màn hình, nhưng vì những quy tắc của
chương trình với moniotrs là sau khi làm tín hiệu một muast quá trình rời
khỏi màn hình ngay lập tức, gây tổn hại không được thực hiện.
Lưu ý rằng nếu sản xuất không UP của nó trên mutex và lá màn hình
trước khi người tiêu dùng đã thực hiện xuống trên mutex, có thể là nhà
sản xuất có thể cố gắng để vào màn hình một lần nữa một cách nhanh
chóng. Tuy nhiên, nỗ lực này sẽ thất bại bởi vì mutex là 0. Chỉ khi người
tiêu dùng các lá màn hình nhà sản xuất có thể nhập lại.
Bây giờ chúng ta hãy xem làm thế nào để thực hiện tin nhắn qua với cờ
tương ứng. Kết hợp với quá trình từng là một semaphore, ban đầu là 0,
trong đó nó sẽ chặn khi gửi hoặc tiếp nhận phải chờ đợi để hoàn tất. Một
vùng đệm được chia sẻ sẽ được sử dụng để giữ các hộp thư, mỗi người có
một loạt các khe thông. Các khe trong hộp thư từng được xích lại với
nhau trong một danh sách liên kết, tin nhắn như vậy được phân phối theo
thứ tự nhận được. Mỗi hộp thư có các biến số nguyên nói như thế nào
nhiều khe có đầy đủ và bao nhiêu là trống rỗng. Cuối cùng. mỗi hộp thư
cũng có sự khởi đầu của hai hàng đợi, đợi một cho các quá trình không
thể gửi đến hộp thư và hàng đợi một cho các quá trình đó là không thể
nhận được từ hộp thư. Các hàng đợi chỉ cần cung cấp những con số quá
trình chờ đợi các quy trình để một Up có thể được thực hiện trên
semaphore có liên quan. Các bộ đệm được chia sẻ toàn bộ được bảo vệ
bởi một semaphore nhị phân. mutex, để đảm bảo rằng chỉ có một quá
trình có thể kiểm tra hoặc cập nhật các cấu trúc dữ liệu được chia sẻ cùng
một lúc. Nó được thể hiện trong hình 2,17.
Khi gửi hoặc tiếp nhận được thực hiện trên một hộp thư có chứa ít nhất
một khe cắm trống hoặc đầy đủ, tương ứng, chèn hoạt động hoặc loại bỏ
một tin nhắn, cập nhật các quầy và các liên kết, và đi ra bình thường.

35
Việc sử dụng mutex lúc bắt đầu và kết thúc của các khu vực quan trọng
đảm bảo rằng chỉ có một quy trình tại một thời điểm có thể sử dụng các
quầy và các điểm, để tránh điều kiện đua.
Khi tiếp nhận được thực hiện trên một hộp thư trống rỗng, quá trình cố
gắng để nhận được tin nhắn đầu tiên vào cứ vào hàng đợi nhận được cho
hộp thư và sau đó làm một UP trên mutex và một DOWN trên semaphore
riêng của mình, do đó đặt chính nó vào giấc ngủ. Sau đó, khi nó được
đánh thức, nó ngay lập tức sẽ làm một DOWN trên mutex giống như
trong các trường hợp sử dụng cờ hiệu điều phối để xây dựng màn hình.
Khi người gửi được thực hiện, nếu ra khỏi phòng trong hộp thư đến, tin
nhắn được đặt ở đó và kiểm tra người gửi để xem hàng đợi nhận cho hộp
thư đã có quá trình chờ đợi. Nếu vậy, một trong những đầu tiên được lấy
ra khỏi hàng đợi, và người gửi không một UP trên semaphore của nó.
Người gửi sau đó ra khỏi khu vực quan trọng và người nhận mới được
đánh thức có thể tiếp tục. DOWN của họ tương ứng và UP trên mutex
hủy bỏ (trong bất cứ điều gì để chúng xảy ra) và không có vấn đề xảy ra,
với điều kiện cũng như với các màn hình, một quá trình mà thức dậy một
quá trình luôn luôn có các wakeup là điều cuối cùng trước khi rời khỏi
khu vực quan trọng.
Khi người gửi không thể hoàn thành do một hộp thư đầy đủ, hàng đợi
người gửi đầu tiên cứ vào hộp thư đến, sau đó làm một UP trên mutex và
một DOWN trên semaphore riêng của mình. Sau đó, khi nhận một
rmoves một tin nhắn từ hộp thư đầy đủ và thông báo rằng ai đó đang xếp
hàng cố gắng gửi đến hộp thư đó, người gửi sẽ được đánh thức.

Sử dụng các bộ điều chỉnh để thực hiện các cờ hiệu điều


phối và tin nhắn (Using monitos to implement semaphores
and Message

36
Thực hiện các cờ hiệu điều phối và tin nhắn bằng cách sử dụng màn
hình sau khoảng cùng một khuôn mẫu như những gì chúng tôi đã được
mô tả, nhưng đơn giản, bởi vì màn hình là một cấp cao hơn xây dựng hơn
so với cờ tương ứng. Để thực hiện semaphore, chúng ta cần một truy cập
và một danh sách liên kết cho mỗi semaphore được thực hiện, cũng như
tình trạng sa biến mỗi quá trình. Khi xuống được thực hiện, kiểm tra
người gọi (bên trong màn hình) để xem các truy cập cho semaphore đó là
lớn hơn số không. Nếu đó là truy cập các bị giảm đi và người gọi đơn
giản là đi ra khỏi màn hình. Nếu truy cập vào là số không, số người gọi
thêm quá trình riêng của mình vào danh sách liên kết cho rằng quảng cáo
của semaphore có một WAIT trên biến điều kiện của mình.
Khi một UP được thực hiện trên một semaphore, việc gia tăng quá
trình gọi điện thoại kiểm tra truy cập (bên trong màn hình, tất nhiên) và
sau đó để xem danh sách liên kết cho semaphore có bất kỳ mục. Nếu
danh sách đã mục, quá trình kêu gọi loại bỏ một trong số đó và không
một tín hiệu trên biến điều kiện cho quá trình đó. Không có quá trình gọi
là không cần thiết để lựa chọn quá trình đầu tiên trên danh sách liên kết.
Trong thực hiện tinh vi hơn, mỗi quá trình có thể đặt ưu tiên của mình
trên danh sách cùng với số xử lý của nó, do đó quá trình ưu tiên cao nhất
sẽ được đánh thức đầu tiên.
Thực hiện các tin nhắn sử dụng màn hình cơ bản cũng giống như với cờ
hiệu, ngoại trừ thay vì một semaphore mỗi quá trình chúng ta có một biến
điều kiện cho mỗi quá trình. Các cấu trúc hộp thư là như nhau cho cả hai
triển khai thực hiện.
Sử dụng tin nhắn để thực hiện các cờ hiệu điều phối và các bộ điều
chỉnh (Using message to implement semaphores and monitors)
Nếu một hệ thống nhắn tin có sẵn, có thể để thực hiện các cờ hiệu điều
phối và giám sát việc sử dụng một mẹo nhỏ. trick là để giới thiệu một quy
trình mới, quá trình đồng bộ hóa. Hãy để chúng tôi đầu tiên xem làm thế

37
nào quá trình này có thể được sử dụng để thực hiện các cờ tương ứng.
Quá trình đồng bộ duy trì một truy cập và danh sách liên kết của các quá
trình chờ đợi quy định cụ thể các hoạt động cho mỗi semaphore. Để làm
một lên hoặc xuống, quá trình một cuộc gọi ông tương ứng (thư viện) thủ
tục, lên hoặc xuống, trong đó gửi thông điệp đến quá trình đồng bộ hóa
quy định cụ thể các hoạt động mong muốn và semaphore được sử dụng.
Các thủ tục sau đó có một thư viện tiếp nhận để có được câu trả lời từ quá
trình đồng bộ hóa.
Khi thông điệp đến, quá trình đồng bộ hóa kiểm tra truy cập để xem
các hoạt động cần thiết có thể được hoàn thành. Up luôn luôn có thể hoàn
thành, nhưng Downs sẽ chặn nếu giá trị của semaphore là 0. Nếu hoạt
động được cho phép, quá trình đồng bộ hóa gửi lại một tin nhắn trống, do
đó bỏ chặn người gọi. Tuy nhiên, nếu hoạt động được trên xuống và
semaphore là 0, quá trình đồng bộ hóa vào người gọi vào hàng đợi và
không gửi một thư trả lời. Kết quả là quá trình làm việc xuống bị chặn,
chỉ cần như nó phải được. Sau đó, whe một UP được thực hiện, quá trình
đồng bộ hóa chọn một trong các quá trình bị cấm tại semaphore, hoặc để
đầu tiên đến, lần đầu tiên được phục vụ, thứ tự ưu tiên, hoặc để một số
khác, và gửi một thư trả lời. Điều kiện chủng tộc được tránh ở đây vì quá
trình đồng bộ xử lý chỉ có một yêu cầu tại một thời điểm.
Màn hình có thể được thực hiện bằng cách sử dụng cùng một thông điệp
lừa. Chúng tôi cho thấy màn hình trước đó ho có thể được thực hiện bằng
cách sử dụng cờ tương ứng. Không có chúng tôi đã chỉ ra semaphore ho
có thể được thực hiện bằng cách sử dụng mesage. Bằng cách kết hợp hai,
chúng tôi nhận được màn hình từ tin nhắn. Một cách để đạt được mục tiêu
này là phải có trình biên dịch thực hiện các thủ tục theo dõi bằng cách gọi
các thủ tục thư viện và doesn cho mutex và mỗi quá trình cờ tương ứng,
như được mô tả ở đầu phần này. Các thủ tục này sau đó sẽ được thực hiện

38
bằng cách gửi tin nhắn đến quá trình đồng bộ hóa. Thực hiện khác cũng
có thể.

2. 3 Các vấn đề về IPC cổ điển(Classical ipc problem)


Các tài liệu hệ điều hành đầy thú vị của vấn đề đã được thảo luận
rộng rãi và phân tích. Trong anh sau phần chúng tôi sẽ xem xét ba trong
những vấn đề tốt hơn được biết đến ..
2.3.1 Các vấn đề các nhà triết lý ẩm thực. (The dining
philosopers problem)
. Năm 1965, Dijkstra đặt ra và giải quyết vấn đề đồng bộ hóa được gọi là
ăn uống vấn đề triết học. Kể từ đó, mọi người phát minh ra thêm một
đồng bộ hóa nguyên thủy đã cố gắng để chứng minh tuyệt vời như thế
nào mới là nguyên thủy bằng cách hiển thị thanh lịch như thế nào nó giải
quyết được vấn đề ăn uống triết học. vấn đề có thể được bắt đầu như sau.
Năm triết gia đang ngồi quanh bàn. Mỗi nhà triết học có một đĩa
spaghetti. Spaghetti là để trơn rằng triết học là một nhu cầu hai dĩa để ăn.
Giữa mỗi tấm là một ngã ba. Bảng này được thể hiện trong hình 2-18.
Cuộc đời của một nhà triết học bao gồm các giai đoạn khác của ăn và
suy nghĩ (đây là cái gì trừu tượng, thậm chí cho triết học, nhưng các hoạt
động khác không liên quan ở đây). Khi một nhà triết học bị đói, cô cố
gắng để có được ngã ba của cô trái và phải, một lúc, tôi để một trong hai.
Nếu thành công trong việc mua hai dĩa, cô ăn một lúc, sau đó đặt xuống
dĩa và tiếp tục suy nghĩ. Câu hỏi chính là: bạn có thể viết một chương
trình cho mỗi nhà triết học mà nó là gì nên làm và không bao giờ xảy ra?
(Nó đã được chỉ ra rằng các yêu cầu hai ngã ba có phần nhân tạo, có lẽ
chúng ta nên chuyển đổi từ Ý đến thực phẩm Trung Quốc, thay thế lúa mì
và đũa cho dĩa)

39
Chúng tôi có thể sửa đổi các chương trình sao cho sau khi ngã ba trái,
kiểm tra chương trình để xem các ngã ba bên phải là thay đổi. Nếu không,
triết học đặt xuống một trái, chờ đợi một thời gian, và sau đó lặp đi lặp lại
toàn bộ quá trình. Đề xuất này cũng vậy, thất bại, mặc dù cho một lý do
khác nhau. Với một chút may mắn, tất cả các nhà triết học có thể bắt đầu
các thuật toán đồng thời, chọn lên dĩa của mình, thấy rằng đĩa quyền của
họ không có sẵn, đặt xuống dĩa trái của họ, chờ đợi, chọn lên dĩa trái của
họ một lần nữa đồng thời, vv , mãi mãi. Một tình huống như thế này,
trong chương trình hicj tất cả các tiếp tục chạy vô thời hạn nhưng không
thực hiện bất kỳ quá trình được gọi là nạn đói. (nó được gọi là đói ngay
cả khi vấn đề không xảy ra trong một tiếng hoặc một nhà hàng Trung
Quốc).
Bây giờ bạn có thể nghĩ. "nếu các nhà triết học chỉ có thể chờ đợi một
thời gian ngẫu nhiên thay vì cùng một thời gian sau khi không đạt được
các ngã ba bên phải, các cơ hội mà tất cả mọi thứ sẽ tiếp tục và bước cho
một giờ thậm chí là rất nhỏ". Quan sát này là đúng, nhưng trong một số
ứng dụng người ta sẽ muốn có một giải pháp mà alays công trình, không
thể không do một loạt các số ngẫu nhiên không. (Hãy suy nghĩ về việc
kiểm soát an toàn tại một nhà máy điện hạt nhân).
Một cải tiến để hình 2-19 mà không có bế tắc và không có đói không có
bảo vệ trong năm báo cáo sau đây gọi để suy nghĩ bởi một semaphore nhị
phân. Trước khi bắt đầu để có được dĩa, một nhà triết học sẽ làm một
DOWN trên mutex. Sau khi thay thế các dĩa, cô sẽ làm một UP trên
mutex. Từ một quan điểm lý thuyết giải pháp này là đầy đủ. Từ một thiết
thực nhất, nó có một lỗi thực hiện: chỉ có một nhà triết học có thể được ăn
tại ngay lập tức bất kỳ. Với năm dĩa có sẵn, chúng tôi sẽ có thể cho phép
hai nhà triết học để ăn cùng một lúc.
Các giải pháp trình bày trong hình 2-20 là chính xác và cho phép xử lý
song song tối đa đối với một số tùy ý của các triết gia. Nó sử dụng một

40
nhà nước mảng, để theo dõi xem có thể di chuyển chỉ vào ăn nhà nước
nếu không phải hàng xóm đang ăn. triết học là các nước láng giềng được
xác định bằng các macro và trái sang phải. Nói cách khác, nếu là 2, còn
lại là 1 và quyền là 3

Chương trình sử dụng một mảng các cờ hiệu, mỗi nhà triết học, do đó,
triết đói có thể chặn nếu các nhánh cần được bận rộn. Lưu ý rằng mỗi quá
trình chạy các triết gia thủ tục tại mã chính của nó, nhưng các thủ tục
khác, đi-dĩa-đặt-nĩa, và thử nghiệm là thủ tục bình thường và không quá
trình riêng biệt
2.3.2 Các vấn đề về người đọc và người viết (The reader and writers
problem)
Các prolem ăn triết học rất hữu ích cho quá trình xây dựng mô hình
nào đang cạnh tranh để truy cập độc quyền cho một số lượng hạn chế các
nguồn lực, chẳng hạn như ổ băng hay tôi khác / thiết bị O. Một vấn đề nổi
tiếng là độc giả và vấn đề nhà văn (Courtois et al ... 1971), trong đó mô
hình truy cập vào một cơ sở dữ liệu. Hãy tưởng tượng một cơ sở dữ liệu
lớn, chẳng hạn như một hệ thống đặt phòng của hãng hàng không, với
nhiều quy trình cạnh tranh có nhu cầu đọc và viết nó. Nó là chấp nhận
được để có nhiều quy trình đọc cơ sở dữ liệu cùng một lúc, nhưng nếu
một quá trình được văn bản (ví dụ. thay đổi) các cơ sở dữ liệu, không có
các quá trình khác có thể truy cập cơ sở dữ liệu, ngay cả người đọc. Câu
hỏi đặt ra là làm thế nào để chương trình độc giả và các nhà văn? Một
giải pháp được thể hiện trong hình 2-21.
Trong giải pháp này, người đọc đầu tiên để có được quyền truy cập
vào cơ sở dữ liệu hiện một DOWN trên db semaphore. Sau đó người đọc
chỉ đơn thuần là tăng một truy cập, rc. Khi độc giả để lại, họ lượng giảm
truy cập và những người cuối cùng ra ngoài không một UP trên
semaphore, cho phép một nhà văn bị chặn, nếu có, để có được in.

41
Tiềm ẩn trong giải pháp này là độc giả có ưu tiên hơn các nhà văn. Nếu
một nhà văn xuất hiện trong khi một số người đọc được trong cơ sở dữ
liệu, các nhà văn phải chờ đợi. Nếu độc giả mới giữ xuất hiện, do đó luôn
luôn có ít nhất một người đọc trong cơ sở dữ liệu, người viết phải giữ chờ
đợi cho đến khi không có nhiều độc giả quan tâm đến các cơ sở dữ liệu.
Courtois cũng trình bày một giải pháp ưu tiên để các nhà văn. Để biết chi
tiết, chúng tôi giới thiệu bạn đến giấy của họ.

2.3.3 Vấn đề người thợ ngủ. (The sleeping barber problem)


Một vấn đề IPC cổ điển diễn ra trong một cửa hàng cắt tóc. Tiệm hớt
tóc có một thợ cắt tóc, thợ cắt tóc một ghế, và ghế n để chờ đợi cho khách
hàng, nếu có, phải ngồi in Nếu không có khách hàng hiện tại, thợ cắt tóc
ngồi xuống trong ghế cắt tóc và ngủ, như minh họa trong hình 2.11. Khi
một khách hàng đến, anh đã đánh thức người thợ cắt tóc ngủ. Nếu khách
hàng bổ sung đến trong khi người thợ cắt tóc được cắt tóc của khách
hàng, họ hoặc là ngồi xuống (nếu có ghế trống) hoặc để lại các cửa hàng
(nếu tất cả các ghế có đầy đủ). Vấn đề là cho chương trình cắt tóc và
khách hàng mà không nhận được vào điều kiện chủng tộc.
Giải pháp của chúng tôi sử dụng ba semaphore: khách hàng, mà số
lượng khách hàng chờ đợi (không bao gồm các khách hàng trong ghế
barner, những người không phải chờ đợi), thợ cắt tóc, số thợ hớt tóc đang
chờ, chờ cho khách hàng (0 hoặc 1), và mutex, mà được sử dụng để loại
trừ lẫn nhau. Chúng ta cũng cần một biến, chờ đợi, mà cũng đếm khách
hàng chờ đợi. Đó là bản chất là một bản sao của khách hàng. Lý do cho
việc chờ đợi là không có cách nào để đọc các giá trị hiện tại của
semaphore, và trong giải pháp này, một khách hàng bước vào cửa hàng
cắt tóc đã để đếm số lượng khách hàng chờ đợi. Nếu nó là ít hơn số ghế,
anh ở lại, nếu không, ông để lại.

42
Giải pháp của chúng tôi là hình 2,23. Khi thợ cắt tóc cho thấy ký làm
việc vào buổi sáng, ông thực hiện các thợ thủ tục, khiến cho ông để chặn
trên của khách hàng cho đến khi ai đó đến semaphore. Ông sau đó đi vào
giấc ngủ như hình 2,22
Khi các khách hàng đầu tiên đến, ông thực hiện khách hàng, bắt đầu
bằng việc mua lại mutex để vào một khu vực quan trọng. Nếu khách hàng
khác vào ngay sau đó, điều thứ hai sẽ không làm bất cứ điều gì ông đầu
tiên đã phát hành mutex. Khách hàng sau đó kiểm tra xem số lượng khách
hàng chờ đợi là ít hơn số ghế. Nếu không, ông phát hành mutex và lá mà
không có một mái tóc.
Nếu có một mái tóc có sẵn, các gia số khách hàng biến số nguyên, chờ
đợi. Sau đó, nó up các semaphore khách hàng, do đó thức dậy người thợ
cắt tóc. Tại thời điểm này, khách hàng, và thợ cắt tóc là cả hai tỉnh táo.
Khi khách hàng phát hành mutex, các thợ cắt tóc lấy nó, không một số vệ
sinh và bắt đầu cắt tóc này.
Khi mái tóc đã qua lối thoát hiểm của khách hàng các thủ tục và rời
khỏi cửa hàng. Không giống như các ví dụ trước của chúng tôi, không có
vòng lặp cho khách hàng vì nhận được một mái tóc là idempotent. Các
vòng thợ cắt tóc, tuy nhiên, và cố gắng để có được những khách hàng tiếp
theo. Nếu có, cắt tóc khác được đưa ra. Nếu không, thợ cắt tóc đi vào giấc
ngủ.

2.4 Lập biểu quá trình


Trong các ví dụ của các phần trước, chúng tôi đã thường xuyên có các
tình huống trong đó hai hoặc nhiều tiến trình (ví dụ, nhà sản xuất và tiêu
dùng) đã được hợp lý Runnable. khi nhiều hơn một quá trình được
Runnable, hệ điều hành phải decde mà một trong những nhiều hơn một
quá trình được Runnable, hệ điều hành phải quyết định cái nào để chạy
đầu tiên. Đó là một phần của hệ điều hành kết nối với quyết định này

43
được gọi là lịch trình, và các thuật toán mà nó sử dụng được gọi là thuật
toán lập lịch.
Quay trở lại những ngày xưa của các hệ thống hàng loạt với đầu vào ở
dạng hình ảnh thẻ trên một băng từ, các thuật toán lập lịch trình rất đơn
giản: chỉ cần chạy các công việc tiếp theo trên băng. với các hệ thống
chia sẻ thời gian đa người dùng, thường kết hợp với công việc hàng loạt
nền, các thuật toán lập kế hoạch phức tạp hơn. Lúc nào có nhiều người
dùng chờ đợi dịch vụ, và cũng có thể được hàng loạt, công việc nền tảng
khác. Ngay cả trong các hệ thống chia sẻ thời gian thuần khiết thường có
việc làm nền, chẳng hạn như hệ thống thư điện tử, thường là chạy tất cả
các thời gian, gửi và nhận mail hoặc mạng lưới tin tức

Trước khi nhìn vào các thuật toán lập lịch trình cụ thể, chúng ta nên suy
nghĩ về những gì mà lịch đang cố gắng để đạt được. Sau khi tất cả, lịch
trình là có liên quan với các quyết định về chính sách, không cung cấp
một cơ chế. Các tiêu chí khác nhau đến để tâm trí như những gì tạo nên
một thuật toán lập kế hoạch tốt. Một số các khả năng rõ ràng hơn bao
gồm:
1. Công bằng: làm cho quá trình chắc chắn mỗi người được chia sẻ
công bằng của các CPU
2. Hiệu quả: giữ cho CPU bận rộn 100 phần trăm thời gian.
3. Thời gian đáp ứng: Giảm thiểu thời gian đáp ứng cho người dùng
tương tác
4. Quay vòng: giảm thiểu thời gian người dùng phải chờ đợi hàng loạt
cho sản lượng
5. Thông qua: tối đa hóa số lượng các công việc xử lý mỗi giờ.
Một ý nghĩ rác sẽ cho thấy rằng một số trong những mục tiêu này mâu
thuẫn. Để giảm thiểu thời gian phản hồi cho người dùng tương tác, các
lịch trình không nên chạy bất kỳ công việc hàng loạt tại tất cả (ngoại trừ

44
3:00-6:00, khi tất cả người dùng tương tác được snug trong giường của
họ). Những người sử dụng hàng loạt có thể sẽ không giống như thuật toán
này, tuy nhiên, nó vi phạm các tiêu chí 4. Nó có thể được hiển thị
(Kleinrock, 1975) rằng bất kỳ thuật toán lập lịch là ưu tiên một số lớp học
của việc làm tổn thương một lớp học của công việc. Số lượng thời gian
CPU có sẵn là hữu hạn, sau khi tất cả. Để cho một người sử dụng nhiều
hơn bạn phải cho người sử dụng ít hơn,. Đó là cuộc sống.

Một biến chứng rằng schedulers phải giải quyết là quá trình từng là duy
nhất và không thể đoán trước. Một số dành nhiều thời gian chờ đợi cho
tập tin I / O, trong khi những người khác sẽ sử dụng CPU hàng giờ tại
một thời điểm nếu có cơ hội. Khi lên lịch bắt đầu chạy một quá trình, nó
không bao giờ biết chắc chắn bao lâu nó sẽ được cho đến khi mà khối quy
trình, hoặc là cho I / O, hoặc trên một semaphore, hoặc vì một lý do khác.
Để chắc chắn rằng không có quá trình chạy quá lâu, gần như tất cả các
máy tính có một bộ đếm thời gian điện tử hoặc đồng hồ được xây dựng
trong, gây một ngắt định kỳ. Một tần số 50 hoặc 60 lần một giây (gọi là
50 hoặc 60 Hertz và viết tắt là Hz) là phổ biến, nhưng trên nhiều máy tính
hệ điều hành có thể thiết lập tần số hẹn giờ để bất cứ điều gì nó muốn. Tại
mỗi quá trình chạy sẽ được phép tiếp tục, hoặc cho dù nó đã có thời gian
CPU đủ cho thời điểm này và phải bị đình chỉ để cung cấp cho một quá
trình của CPU.
Chiến lược của việc cho phép các quá trình được một cách hợp lý
Runnable để được tạm đình chỉ được gọi là lập kế hoạch ưu tiên, và là trái
ngược với phương pháp chạy để hoàn thành các hệ thống hàng loạt đầu.
Run để hoàn thành cũng được gọi là nonpreemptive lịch. Như chúng ta đã
thấy trong chương này, một quá trình có thể bị đình chỉ tại một tức tùy ý,
mà không có cảnh báo, do đó, quá trình khác có thể được chạy.
Điều này dẫn đến điều kiện chủng tộc và đòi cờ hiệu, quầy sự kiện, màn

45
hình, tin nhắn, hoặc một số phương pháp khác tinh vi để phòng ngừa
chúng. Mặt khác, một chính sách cho phép một quá trình chạy miễn là nó
muốn sẽ có nghĩa là máy tính (số bi) ai đó đến một tỷ nơi có thể phủ nhận
dịch vụ cho tất cả người dùng khác vô thời hạn.

Vì vậy mặc dù các thuật toán lập lịch nonpreemptive rất đơn giản và dễ
thực hiện, chúng thường không thích hợp cho mục đích chung hệ thống
có sử dụng nhiều cạnh tranh. Mặt khác, đối với một hệ thống riêng, như
là một hệ thống cơ sở dữ liệu, nó cũng có thể là hợp lý cho quá trình tổng
thể để bắt đầu một tiến trình con làm việc theo yêu cầu và để cho nó chạy
cho đến khi nó hoàn thành. Sự khác biệt với hệ thống mục đích chung là
tất cả các quá trình trong hệ thống cơ sở dữ liệu được dưới sự kiểm soát
của một tổng thể duy nhất, mà mỗi đứa trẻ biết được những gì sẽ làm và
khoảng bao lâu nó sẽ mất.
2.4.1 Lịch biểu Round Robin(kiểu xoay tròn)
Bây giờ chúng ta xem xét một số thuật toán lập lịch trình cụ thể. Một
trong những lâu đời nhất, đơn giản, chính xác nhất, và các thuật toán
được sử dụng rộng rãi nhất là vòng luân chuyển. Mỗi quá trình được chỉ
định một khoảng thời gian, được gọi là lượng tử, mà nó được phép chạy.
Nếu quá trình vẫn chạy vào cuối học lượng tử, các CPU được ưu tiên và
cho đến quá trình khác. Nếu quá trình này đã bị chặn thành phẩm trước
khi lượng tử đã trôi qua, việc chuyển đổi CPU được thực hiện khi các
khối quy trình, tất nhiên. Round robin là dễ thực hiện. Tất cả các lịch
trình cần phải làm là duy trì một danh sách các quá trình Runnable, như
hình 2,24 (a). Khi lượng tử chạy ra trên một quy trình, nó được đặt ở cuối
danh sách, như hình 2,24 (b).
Các chỉ thú vị quanh vấn đề với robin là chiều dài của lượng tử. Chuyển
từ một quá trình khác đòi hỏi một lượng thời gian nhất định để thực hiện

46
việc quản lý tiết kiệm và tải đăng ký và bản đồ bộ nhớ, cập nhật các bảng
khác nhau và danh sách, vv Giả sử quá trình chuyển đổi này hoặc chuyển
đổi bối cảnh, vì nó là đôi khi được gọi, mất 5 msec . Giả sử lượng tử được
đặt tại 20 msec. Với các thông số này, sau khi thực hiện 20 msec công
việc hữu ích, CPU sẽ phải mất 5 msec vào quá trình chuyển đổi. Hai
mươi phần trăm thời gian CPU sẽ bị lãng phí về hành chính.

Để nâng cao hiệu quả CPU, chúng ta có thể thiết lập các lượng tử để, nói,
500 msec. Bây giờ lãng phí thời gian ít hơn 1 phần trăm. Nhưng xem xét
những gì sẽ xảy ra nếu người dùng tương tác mười nhấn phím trở lại vận
chuyển tại thời điểm gần giống nhau. Mười quy trình sẽ được đưa vào
danh sách các quá trình Runnable. Nếu CPU là nhàn rỗi, các onr đầu tiên
sẽ bắt đầu ngay lập tức, điều thứ hai có thể không bắt đầu cho đến khi
khoảng 1 / 2 giây sau đó, và như vậy. Các kém may mắn nhất có thể phải
chờ 5 giây trước khi nhận được một cơ hội, giả sử tất cả những người
khác sử dụng lượng tử đầy đủ của họ. Hầu hết người dùng sẽ cảm nhận
được một phản ứng 5 giây để một lệnh ngắn là khủng khiếp.
Kết luận này có thể được hình thành như sau: thiết lập các lượng tử quá
ngắn quá trình gây ra quá nhiều thiết bị chuyển mạch và làm giảm hiệu
quả CPU, nhưng đặt nó quá dài có thể gây ra phản ứng kém với các yêu
cầu tương tác ngắn. Một lượng tử khoảng 100 msec thường là một thỏa
hiệp hợp lý.

2.4.2 ưu tiên lập kế hoạch (Priority scheduling)


Round robin lập kế hoạch làm cho các giả định ngầm rằng tất cả các
quy trình đều quan trọng. Thông thường, những người sở hữu và vận
hành các trung tâm máy tính có ý tưởng khác nhau về chủ đề đó. Tại một
trung tâm máy tính trường đại học, trình tự mổ có thể là hiệu trưởng đầu
tiên, sau đó các giáo sư, thư ký, người lao công, và cuối cùng là sinh viên.

47
Sự cần thiết phải có yếu tố bên ngoài vào tài khoản dẫn đến lập kế hoạch
ưu tiên. Ý tưởng cơ bản là, thẳng về phía trước: mỗi quá trình được chỉ
định một ưu tiên, và quá trình runnble với ưu tiên cao nhất được phép
chạy.
Để ngăn chặn các quá trình ưu tiên cao từ các hoạt động vô thời hạn,
việc lập kế hoạch ay giảm ưu tiên của quá trình hiện đang chạy ở mỗi
đánh dấu đồng hồ (ví dụ, ở mỗi đồng hồ gián đoạn). Nếu hành động này
gây ra ưu tiên giảm xuống dưới đó của quá trình cao nhất kế tiếp, một quá
trình chuyển đổi xảy ra.
Ưu tiên có thể được giao cho quá trình tĩnh hay động. Trên một máy tính
quân sự, quy trình bắt đầu bởi tướng có thể bắt đầu ở mức ưu tiên 100,
quá trình bắt đầu bởi đại tá ở 90, chuyên ngành tại 80, thuyền trưởng ở
mức 70, trung úy tại 60, và như vậy. Ngoài ra, tại một trung tâm máy tính
thương mại, ưu tiên cao công việc có thể chi phí 100 $ một giờ, trung ưu
tiên 75 $ một giờ, và ưu tiên thấp 50 $ n giờ. Các hệ thống UNIX có một
lệnh, đẹp, cho phép người dùng tự nguyện giảm mức ưu tiên của quá
trình của mình, để được tốt đẹp cho người dùng. Không ai bao giờ sử
dụng nó.
Ưu tiên có thể được gán tự động bởi hệ thống hệ thống để đạt được mục
tiêu nhất định. Ví dụ, một số quy trình được đánh giá cao I / O kết abd
dành phần lớn thời gian của họ chờ đợi cho I / O để hoàn thành. Bất cứ
khi nào như một quá trình muốn CPU, nó cần được CPU ngay lập tức, để
cho nó bắt đầu, tôi tiếp theo của nó / O yêu cầu, whih sau đó có thể tiến
hành trong parallet với quá trình khác thực sự tính toán. Làm cho I / O bị
ràng buộc quá trình chờ đợi một thời gian dài cho các CP chỉ có nghĩa là
có nó trên bộ nhớ chiếm trong một thời gian dài không cần thiết. Một
thuật toán đơn giản để cho dịch vụ tốt cho I / O là bị ràng buộc quá trình
thiết lập các ưu tiên đến 1 / f, trong đó f là phần nhỏ so với lượng tử cuối
cùng mà một quá trình sử dụng. Một quá trình được sử dụng chỉ 2 ms của

48
lượng tử msec của 100 sẽ được ưu tiên 50, trong khi một quá trình chạy
50 msec trước khi chặn sẽ được ưu tiên 2, và một quá trình được sử dụng
toàn bộ lượng tử sẽ được ưu tiên 1
Nó thường được thuận tiện cho quá trình nhóm vào lớp ưu tiên và lập
kế hoạch ưu tiên sử dụng trong các lớp học, nhưng lập kế hoạch luân
chuyển quanh trong mỗi lớp. Hình 2,25 cho thấy một hệ thống với bốn
lớp ưu tiên. Các thuật toán lập lịch trình như sau: miễn là có các quá trình
Runnable trong 4 lớp ưu tiên, chỉ cần chạy mỗi người đối với một lượng
tử, thời trang ronbin tròn, và không bao giờ bận tâm với các lớp ưu tiên
thấp hơn. Nếu ưu tiên lớp 4 là trống rỗng, sau đó chạy vòng robin 3 quá
trình học. Nếu các lớp 4 và 3 là cả trống rỗng, sau đó chạy lớp.
2.4.3 Nhiều hàng đợi.
Một trong những lập kế hoạch ưu tiên sớm nhất là vào CTSS (Corbato
et al .., 1962). CTSS đã có vấn đề quá trình chuyển đổi là rất chậm vì
17094 có thể giữ chỉ có một quá trình trong bộ nhớ. Mỗi chuyển đổi có
nghĩa là quá trình hiện hành vào đĩa và đọc sách trong một cái mới từ đĩa.
Các nhà thiết kế CTSS nhanh chóng nhận ra rằng đó là hiệu quả hơn để
cung cấp cho các quá trình CPU-ràng buộc một lượng tử lớn một lần
trong một, thay vì cho họ lượng tử nhỏ thường xuyên (để giảm trao đổi)
Mặt khác,. cho tất cả các quy trình một lượng tử lớn có nghĩa là thời gian
đáp ứng kém, như chúng ta đã nhìn thấy. Giải pháp của họ là để thiết lập
các lớp ưu tiên. Quy trình ine lớp cao nhất đã được chạy với một lượng
tử. Các quá trình trong lớp cao nhất kế tiếp đã được chạy trong hai lượng
tử. Các quá trình trong lớp tiếp theo được thực cho bốn lượng tử, và như
vậy. Bất cứ khi nào một quá trình sử dụng hết tất cả các lượng tử giao cho
nó, nó đã được chuyển xuống một lớp.
Ví dụ,. xem xét một quá trình cần thiết để tính liên tục cho 100 lượng tử.
Nó ban đầu sẽ được cung cấp một lượng tử, sau đó chuyển ra. Tiếp theo
thời gian nó sẽ nhận được hai lượng tử trước khi được chuyển ra. Ngày

49
kế tiếp chạy nó sẽ có 4, 8,16, 32 và lượng tử 64. mặc dù nó đã có thể sử
dụng chỉ 37 của lượng tử 64 cuối cùng để hoàn thành công việc của mình.
Chỉ có 7 giao dịch hoán đổi sẽ là cần thiết (bao gồm cả các phụ tải ban
đầu) thay vì 100 với một thuật toán tinh khiết robin tròn. Hơn nữa, quá
trình chìm sâu hơn và sâu hơn vào các hàng đợi ưu tiên, nó sẽ được chạy
ít hơn và ít thường xuyên hơn, tiết kiệm các CPU cho ngắn, quá trình
tương tác

Các chính sách sau đây đã được thông qua để ngăn chặn một quá trình
cần thiết để chạy trong một thời gian lâu dài khi nó lần đầu tiên bắt đầu,
nhưng đã trở nên tương tác, không bị trừng phạt mãi mãi. Bất cứ khi nào
quay trở lại vận chuyển đã được đánh máy tại thiết bị đầu cuối, quá trình
thuộc thiết bị đầu cuối đã được chuyển đến các lớp ưu tiên cao nhất, trên
giả định rằng nó đã được về để trở thành tương tác. Một ngày đẹp trời
một số người dùng với một quá trình CPU-bound heavilly phát hiện ra
rằng chỉ cần ngồi tại thiết bị đầu cuối và đánh trả về vận chuyển một cách
ngẫu nhiên mỗi vài giây đã kỳ diệu đối với thời gian phản ứng của mình.
Ông nói với tất cả bạn bè của hắn. Đạo đức của câu chuyện: nhận được
nó ngay trong thực tế có nhiều khó khăn hơn so với việc nó đúng nguyên
tắc.
Nhiều thuật toán khác đã được sử dụng cho giao quy trình để các lớp ưu
tiên. Ví dụ, XDS có ảnh hưởng hệ thống 940 (Lampson, 1968), được xây
dựng tại Berkeley, có bốn lớp ưu tiên, được gọi là thiết bị đầu cuối, I / O,
ngắn học lượng tử, và dài hạn lượng tử. Khi một quá trình đang chờ đợi
đầu vào thiết bị đầu cuối cuối cùng đã được đánh thức, nó đã đi vào các
lớp ưu tiên cao nhất (terminal). Khi một quá trình chờ đợi cho một khối
đĩa trở nên sẵn sàng, nó đã đi vào lớp thứ hai. Khi một quá trình vẫn còn
chạy khi lượng tử của nó chạy ra, nó bước đầu đã được đặt trong lớp thứ
ba. Tuy nhiên, nếu một quá trình sử dụng hết lượng tử của nó quá nhiều

50
lần liên tục mà không ngăn chặn đối với thiết bị đầu cuối hoặc các I / O,
nó đã được chuyển xuống hàng dưới cùng. Nhiều hệ thống khác sử dụng
một cái gì đó tương tự để ưu tiên cho người dùng tương tác.

2.4.4 Công việc ngắn nhất đầu tiên (Shortest job first)
Hầu hết các thuật toán trên được thiết kế cho các hệ thống tương tác.
Bây giờ chúng ta nhìn vào một trong đó là đặc biệt thích hợp cho việc
tắm mà lần un được biết trước. Trong một công ty bảo hiểm, ví dụ, người
ta có thể dự đoán khá chính xác bao lâu nó sẽ làm để chạy hàng loạt của
1000 tuyên bố, kể từ khi công việc tương tự được thực hiện mỗi ngày.
Khi một số công việc quan trọng không kém là ngồi trong hàng đợi đầu
vào chờ đợi để được bắt đầu, các lịch trình công việc ngắn mạch nên sử
dụng đầu tiên. Nhìn vào hình 2-26. Ở đây chúng ta tìm thấy bốn công
việc A, B, C và D, với thời gian chạy của 8,4,4, và 4 phút, cho B là 12
phút, cho C là 16 phút, và D là 20 phút, cho một trung bình là 14 phút.
Bây giờ chúng ta xem xét hoạt động bốn công việc bằng cách sử dụng
công việc ngắn nhất đầu tiên, như hình 2,26 (b). thời gian quay vòng hiện
nay 4, 8,12 và 20 phút, cho trung bình 11 phút. Ngắn nhất có thể chứng
minh công việc đầu tiên là tối ưu. Hãy xem xét trường hợp của bốn công
việc, với thời gian chạy của a, c, b và d, tương ứng Các kết thúc công việc
đầu tiên tại một thời điểm, kết thúc thứ hai tại một thời điểm + b, và như
vậy. Thời gian đáp có nghĩa là thời gian, do đó, nó nên là công việc ngắn
nhất, với b tiếp theo, sau đó c và d cuối cùng là lâu nhất vì nó chỉ ảnh
hưởng đến thời gian quay vòng của mình. Các đối số cũng được áp dụng
như nhau cho bất kỳ số lượng việc làm.
Bởi vì công việc đầu tiên ngắn nhất sẽ luôn luôn tạo thời gian phản ứng
tối thiểu trung bình, nó sẽ được tốt đẹp nếu nó có thể được sử dụng cho
các quá trình tương tác như là tốt. Đến một mức độ nhất định, nó có thể

51
được. Quá trình tương tác thường thực hiện theo các mẫu của chờ đợi
lệnh, thực hiện lệnh, đợi lệnh, lệnh Thi công, và như vậy. Nếu chúng ta
về việc thực hiện mỗi lệnh là một "công việc" riêng biệt, sau đó chúng tôi
sẽ giảm thiểu thời gian phản ứng tổng thể bằng cách chạy ngắn nhất đầu
tiên. Vấn đề duy nhất là việc chỉ ra các các quy trình hiện Runnable là
một trong ngắn nhất.
Một phương pháp là làm cho các ước tính dựa trên hành vi trong quá
khứ và chạy các quá trình với thời gian ngắn nhất chạy ước tính. Giả sử
các ước tính mỗi lệnh cho một số thiết bị đầu cuối là T0. Bây giờ giả sử
chạy tiếp theo của nó được đo được T1. Chúng tôi có thể cập nhật ước
tính của chúng tôi bằng cách lấy tổng trọng số của hai số, đó là, aT0 + (1-
a) T1. Thông qua sự lựa chọn của một chúng ta có thể quyết định có quá
trình dự toán cũ quên chạy nhanh, hoặc ghi nhớ chúng trong một thời
gian dài. Với a = 1 / 2, chúng tôi nhận được ước tính kế tiếp của
T0, T0 / 2 + T1 / 2, T0 / 4 + T1 / 4 + T2 / 2, T0 / 8 + T1 / 8 + T2 / 4 +
T3 / 2
Như vậy, sau ba chạy mới, trọng lượng của T0 trong dự toán mới đã giảm
tới 1 / 8
Kỹ thuật đánh giá giá trị tiếp theo trong một loạt bằng cách lấy giá trung
bình của giá trị đo được hiện tại và ước tính trước đó là đôi khi được gọi
là lão hóa. Nó được áp dụng cho nhiều tình huống mà dự báo phải được
thực hiện dựa trên các giá trị trước đó. Lão hóa là đặc biệt là dễ thực hiện
khi a = 1 / 2. Tất cả những gì cần thiết là để quảng cáo các giá trị mới cho
các dự toán hiện hành và phân chia số tiền của 2 (bằng cách chuyển nó
đúng 1 bit).
Đó là giá trị chỉ ra rằng các công việc ngắn nhất đầu tiên của thuật
toán chỉ là tối ưu khi tất cả các việc làm có sẵn đồng thời. Ví dụ như truy
cập, xem xét năm công việc, từ A đến E, với thời gian chạy của 2,4,1,1,
và 1, tương ứng. Bộ đếm thời gian đến của họ là 0, 0,3,3, và 3.

52
Ban đầu, chỉ có A hoặc B có thể được lựa chọn, kể từ khi đặt hàng ba
công việc đã không đến được. Sử dụng công việc ngắn nhất đầu tiên
chúng ta sẽ chạy các công việc theo thứ tự A, B, C, D, E cho một chờ đợi
trung bình là 4.6. Tuy nhiên, chạy chúng theo thứ tự B, C, D, E, A đã chờ
đợi một bình quân là 4,4.

2.4.5 Lập kế hoạch bảo đảm (Guaranteed Scheduling)


Một cách tiếp cận hoàn toàn khác nhau để lập kế hoạch là làm cho lời hứa
thực sự cho người dùng về hiệu suất và sau đó sống với họ. Một lời hứa
đó là thực tế để thực hiện và dễ dàng để sống tới là: Nếu thre là n người
dùng đăng nhập trong khi bạn đang làm việc, bạn sẽ nhận được khoảng
1 / n về sức mạnh của CPU.
Để thực hiện tốt lời hứa này, hệ thống phải theo dõi CPU bao nhiêu thời
gian người dùng đã có cho tất cả các quá trình của ông kể từ khi đăng
nhập, và cũng bao lâu mỗi người dùng đã đăng nhập này sau đó tính toán
số lượng thời gian CPU mỗi người dùng có thực sự đã có được cũng được
biết đến, nó là đơn giản để tính toán tỷ lệ của CPU thực tế đã có thời gian
CPU được. Một tỷ lệ là 0,5 có nghĩa là một quá trình chỉ có một nửa của
những gì nó cần phải có, và một tỷ lệ là 2.0 có nghĩa là một quá trình đã
có hai lần càng nhiều như nó đã được hưởng. Thuật toán sau đó để chạy
quá trình với tỷ lệ thấp nhất cho đến khi tỷ lệ của nó đã di chuyển trên đối
thủ cạnh tranh gần nhất của nó.
Một ý tưởng tương tự có thể được áp dụng cho các hệ thống thời gian
thực, trong đó có thời hạn tuyệt đối phải được đáp ứng. Ở đây ta nhìn cho
quá trình nguy hiểm nhất của thiếu thời hạn của nó, và chạy nó lần đầu
tiên. Một quá trình cần được hoàn thành trong 10 giây được ưu tiên hơn
là phải hoàn thành trong 10 phút.

53
2.4.6 Chính sách so với cơ chế(Policy versus Mechanism)
Cho đến nay, chúng tôi đã mặc nhiên giả định rằng tất cả các quá
trình trong hệ thống thuộc về người sử dụng khác nhau và vì thế cạnh
tranh cho CPU. Trong khi điều này thường tre, đôi khi, nó sẽ xảy ra rằng
một quá trình có nhiều trẻ em đang chạy dưới sự kiểm soát của nó. Ví dụ,
một quy trình quản lý cơ sở dữ liệu hệ thống có thể có nhiều trẻ em. Mỗi
đứa trẻ có thể làm việc trên một yêu cầu khác nhau, hoặc mỗi người có
thể có một số chức năng secific để thực hiện (truy vấn phân tích, truy cập
đĩa, vv.) Đó là hoàn toàn có thể là quá trình chính có một ý tưởng tuyệt
vời trong đó có trẻ em của nó là imortant nhất (hoặc thời gian quan trọng)
và có ít nhất. Thật không may, không có schedulers thảo luận ở trên chấp
nhận bất kỳ đầu vào từ người sử dụng các quy trình về lập kế hoạch quyết
định. Kết quả là, lên lịch và hiếm khi làm cho sự lựa chọn tốt nhất.
Giải pháp cho vấn đề này là để tách các cơ chế lập kế hoạch từ các chính
sách lập lịch. Điều này có nghĩa là thuật toán lập lịch là parametrized một
cách nào đó, nhưng các thông số có thể được ghi vào các tiến trình người
dùng. Chúng ta hãy xem xét ví dụ cơ sở dữ liệu một lần nữa. Giả sử hạt
nhân sử dụng thuật toán lập kế hoạch theo cách diển dịch, nhưng cung
cấp một hệ thống gọi mà một quá trình có thể thiết lập (và thay đổi) các
ưu tiên của các con của nó. Bằng cách này phụ huynh có thể kiểm soát cụ
thể như thế nào, sinh của mình được lên kế hoạch, mặc dù bản thân nếu
không làm như lập kế hoạch. Ở đây cơ chế này là hạt nhân, nhưng chính
sách này do một quá trình người dùng.
2.4.7 Lập kế hoạch hai mức (Two -level scheduling)
Cho đến bây giờ chúng tôi có ít nhiều giả định rằng tất cả các quy
trình Runnable nằm trong bộ nhớ chính. Nếu không đủ bộ nhớ chính í có
sẵn, một số các quy trình Runnable sẽ phải được lưu giữ trên ổ đĩa. Tình
hình này có ý nghĩa lớn đối với lịch trình, vì quá trình chuyển đổi thời

54
gian để mang lại nad chạy một quá trình từ đĩa là bậc độ lớn hơn chuyển
sang một alredy quá trình trong bộ nhớ chính
Một cách thực tế hơn đối phó với quá trình ra trao đổi là sử dụng một
lịch trình hai cấp. Một số tập hợp con của các quá trình runnble là lần đầu
tiên được nạp vào bộ nhớ chính, s hình 2,27 (a). Các kế hoạch sau đó hạn
chế bản thân để lập lịch chỉ là quá trình tập hợp này trong một thời gian.
Định kỳ, một lịch trình ở cấp cao hơn được gọi để loại bỏ những tiến
trình đã được trong bộ nhớ đủ dài và để tải các quy trình đã được trên đĩa
quá dài. Sau khi thay đổi đã được thực hiện, như trong hình 2-27 (b), các
lịch trình cấp dưới lại hạn chế bản thân để chỉ chạy những quá trình đang
thực sự trong bộ nhớ. Như vậy, lịch trình cấp dưới liên quan đến việc làm
một sự lựa chọn trong số các quy trình Runnable được trong bộ nhớ tại
thời điểm đó, trong khi lịch cao cấp có liên quan với quá trình con thoi
qua lại giữa bộ nhớ và đĩa.

Trong số các tiêu chí mà cấp trên lịch trình có thể sử dụng để thực hiện
quyết định của mình là những người sau đây.
1. Bao lâu nó được kể từ khi quá trình này đã được đổi chỗ ở hay ra?
2. Làm thế nào có nhiều thời gian CPU quá trình gần đây?
3. Làm thế nào lớn là quá trình này? (những cái nhỏ sẽ có trong đường)
4. Bao lâu ông ưu tiên của quá trình này?
Một lần nữa ở đây chúng tôi có thể sử dụng luân chuyển vòng, lập kế
hoạch ưu tiên, hoặc bất kỳ phương pháp khác nhau khác.
2,5 Tóm tắt (Summary)
Để ẩn những tác động của các ngắt, hệ điều hành cung cấp một mô
hình khái niệm bao gồm các quy trình tuần tự chạy song song. Mỗi quá
trình có nhà nước riêng của mình, và có thể được coi như là chạy trên bộ
vi xử lý ảo của riêng mình.

55
Đôi khi quá trình có thể tương tác, ví dụ, chia sẻ một vùng đệm chung.
Tương tác này có thể dẫn đến điều kiện chủng tộc, tình huống trong đó
xác định chính xác thời gian kết quả. điều kiện chủng tộc dẫn đến hành vi
đó không phải là tái sản xuất.
Để tránh điều kiện chủng tộc, chúng tôi giới thiệu khái niệm của một
khu vực quan trọng, đó là một phần của mã trong đó có một quá trình
đang làm cái gì đó để tình trạng chia sẻ, và không muốn quá trình khác
làm việc có quá. Phần quan trọng cung cấp loại trừ lẫn nhau.
Quá trình có thể giao tiếp với nhau bằng cách sử dụng các thông tin liên
lạc nguyên thủy InterProcess. Những nguyên thủy được sử dụng để đảm
bảo rằng không có hai quá trình là bao giờ trong các phần quan trọng của
họ tại cùng một thời gian, chiếc mũ là, để đảm bảo loại trừ lẫn nhau. Một
quá trình có thể được chạy, Runnable, hoặc bị chặn và có thể tính phí nhà
nước khi nó hay quá trình khác thực hiện một trong những nguyên thủy
InterProcess truyền thông

Các thông tin liên lạc InterProcess nguyên thủy đã được đề xuất. Trong số
này có cờ hiệu điều phối, giám sát, quầy sự kiện, và qua tin nhắn. Về mặt
lý thuyết, họ là tương đương, trong đó một số có thể được sử dụng để
thực hiện những người khác. Trong các hệ thống thực tế, cờ hiệu và thông
điệp truyền được sử dụng rộng rãi nhất.
Một số vấn đề cổ điển đã được giải quyết bằng cách sử dụng này và các
nguyên thủy. Trong thực tế, những thử nghiệm đầu tiên của bất kỳ mới
được đề xuất nguyên thủy là để xem nó như thế nào giải quyết vấn đề cổ
điển. Chúng bao gồm những người tiêu dùng, sản xuất, phòng ăn, nhà
triết học, đọc và các nhà văn và các vấn đề thợ cắt tóc ngủ. Ngay cả với
nguyên thủy thích hợp, chăm sóc đã được thực hiện để tránh lỗi và khóa
chết.
Nhiều schecduling thuật toán được biết đến. Công việc của một thuật toán

56
lập lịch là để xác định quá trình chạy tiếp theo, có tính đến yếu tố xem xét
như là thời gian phản ứng, hiệu quả, và công bằng. Cũng được biết đến
thuật toán lập kế hoạch bao gồm robin tròn, lập kế hoạch ưu tiên, xếp
hàng đa cấp, công việc ngắn nhất đầu tiên, và lập kế hoạch đảm bảo.
Trong một số hệ thống, cơ chế lập kế hoạch và chính sách lập lịch trình
được chia, cho phép tăng tính linh hoạt

57

You might also like