You are on page 1of 11

Trong hệ điều hành LINUX, chúng ta có chủ yếu 2 loại quy trình là:

+ Quy trình thời gian thực (real-time)


+ Quy trình thông thường (nomal)

I. Quy trình thời gian thực:


Là các quy trình không thể bị trì hoãn trong bất kỳ tình huống nào. Được gọi là các quy trình
khẩn cấp.
Có 2 loại:
1. First in-first out (SCHED_FIFO)
- Chính sách SCHED_FIFO khác SCHED_RR ở điểm là không sử dụng time
slice. Theo đó tiến trình đang chiếm dụng CPU sẽ tiếp tục chạy cho đến khi
có một trong các sự kiện sau:

 Tiến trình tự động nhường CPU, tương tự như chính sách SCHED_RR ở
trên
 Tiến trình bị kết thúc
 Tiến trình bị chiếm quyền bởi một tiến trình có độ ưu tiên cao hơn

- Trong trường hợp 1, tiến trình sau khi bị chiếm quyền sẽ bị đẩy vào cuối
queue của các tiến trình cùng priority. Với trường hợp 3, tiến trình bị chiếm
quyền được đẩy vào đầu của queue, sau khi tiến trình có độ ưu tiên cao hơn
dừng chiếm dụng CPU, nó sẽ tiếp tục thực thi.

2. Round-robin (SCHED_RR)

- Với cơ chế SCHED_RR, các tiến trình chạy tuân theo cơ chế round-robin
(time-sharing): mỗi tiến trình được cấp một khoảng thời gian (hay khe thời
gian) cố định được gọi là time slice. Khi một tiến trình chạy, nó sẽ chiếm giữ
CPU cho đến khi xảy ra một trong các sự kiện sau:

 Thời gian tiến trình chạy bằng time slice được cấp cho nó
 Tiến trình tự động nhường CPU, trường hợp này xảy ra khi tiến trình gọi một
blocking system call hoặc gọi system call sched_yield().
 Tiến trình bị kết thúc
 Tiến trình bị chiếm quyền bởi một tiến trình có độ ưu tiên cao hơn.

- Với trường hợp 1 và 2 ở trên, tiến trình sau khi bị mất quyền chiếm giữ CPU
sẽ bị đẩy vào cuối của queue với cùng các tiến trình cùng priority khác. Với
trường hợp 4, tiến trình bị chiếm quyền được đẩy vào đầu của queue, sau khi
tiến trình độ ưu tiên cao hơn chạy hết time slice, nó sẽ tiếp tục thực thi cho
đến khi đi hết time slice của mình.
- Như vậy, tổng kết với 2 scheduling policy SCHED_RR và
SCHEF_FIFO cho real-time process, tiến trình đang chạy bị
chiếm quyền trong các trường hợp sau:

 Tiến trình có độ ưu tiên cao hơn đang bị block (gọi một block I/O
system call như read(), select()…) chuyển sang trạng thái unblock
 Độ ưu tiên của một tiến trình được tăng lên cao hơn so với tiến
trình đang chạy
 Độ ưu tiên của tiến trình đang chạy bị giảm xuống thấp hơn so với
một tiến trình nào đó đang ở trạng thái runable.

II. Quy trình thường:


Ngược lại với quy trình thời gian thực

3. Nomal (SCHED_NOMAL or SCHED_OTHER)


SCHED_NORMAL / SCHED_OTHER là chính sách lập lịch tiêu chuẩn hoặc
mặc định được sử dụng trong hệ điều hành LINUX. Cơ chế chia sẻ thời gian
được sử dụng trong chính sách thông thường. Cơ chế chia sẻ thời gian có nghĩa là
chỉ định một số lượng thời gian cụ thể cho một quy trình để thực hiện nó. Chính
sách thông thường xử lý tất cả các luồng của quy trình không cần bất kỳ cơ chế
thời gian thực nào.

4. Batch (SCHED_BATCH)
Scheduling policy SCHED_BATCH được đưa vào Linux kerne từ version
2.6.16, có thể dùng để lập lịch cho các batch process. Chính sách này hơi giống
với chính sách SCHED_NORMAL. Chính sách SCHED_BATCH xử lý các quy
trình không tương tác hữu ích trong việc tối ưu hóa thời gian thông lượng của
CPU. Chính sách lập lịch trình SCHED_BATCH được sử dụng cho một nhóm
các quy trình có mức độ ưu tiên: 0.

5. Idle (SCHED_IDLE)
Scheduling policy SCHED_IDLE được đưa vào Linux kernel từ version 2.6.23.
Chính sách lập lịch này cũng tương tự như policy SCHED_NORMAL.
SCHED_IDLE xử lý các quy trình có Mức độ ưu tiên cực thấp. Các tác vụ có
mức độ ưu tiên thấp là các tác vụ được thực thi khi hoàn toàn không có tác vụ
nào được thực thi. Chính sách SHED_IDLE được thiết kế cho các tác vụ có mức
độ ưu tiên thấp nhất của hệ điều hành.
VD:
Round-robin:

Quantum time = 3 (time slice)

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Waiting time:

P1 = 0

P2 = 13 – 0 – 4 = 9 ( 2 quá trình đợi từ 0->3 của P1 và từ 6->12 của P3 P4)

P3 = 14 – 3 – 4 = 7 ( 2 quá trình đợi từ 3->6 của P2 và từ 9->13 của P2 P4)

P4 = 15 – 5 – 4 = 6 ( 2 quá trình đợi từ 5->9 của P2 P3 và từ 12->14 của P2 P3)

Waiting time avg = (9+7+6)/4 = 5.5


Tunrnaround time:

P1 = 3 + 0 = 3

P2 = 4 + 9 = 13

P3 = 4 + 7 = 11

P4 = 4 + 6 = 10

Tunrnaround time avg = (3+13+11+10)/4 = 9.25


First in-first out

Tiến trình:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Waiting time:
P1 = 0

P2 = 3 – 0 = 3

P3 = 7 – 3 = 4

P4 = 11 – 5 = 6

Waiting time avg = (3+4+6)/4 = 3.25

Tunrnaround time:
P1 = 3 + 0 = 3

P2 = 4 + 3 = 7

P3 = 4 + 4 = 8

P4 = 4 + 6 = 10

Tunrnaround time avg = (3+7+8+10)/4 = 7


Linux Scheduling ( was 5.6.3 )

 Trước phiên bản 2.5, Linux sử dụng thuật toán lập lịch UNIX truyền thống.
 Phiên bản 2.6 sử dụng thuật toán được gọi là O(1), thuật toán này chạy trong
thời gian không đổi bất kể số lượng tác vụ và cung cấp hỗ trợ tốt hơn cho các
hệ thống SMP. Tuy nhiên, nó mang lại hiệu suất tương tác kém.
 Bắt đầu từ 2.6.23, CFS, Complete Fair Scheduler, đã trở thành hệ thống lập
lịch tiêu chuẩn của Linux, Nó là sự thay thế cho mã tương tác
SCHED_OTHER của trình lập lịch trình cố định trước đó.

CFS là viết tắt của "Completely Fair Scheduler".

TỔNG QUAN

 80% thiết kế của CFS có thể được tóm tắt trong một câu: CFS về cơ bản mô
hình hóa một " ideal, precise multi-tasking CPU"( CPU đa tác vụ chính xác, lý
tưởng) trên real hardware.

 " Ideal multi-tasking CPU"(không tồn tại :-)) là CPU có 100% sức mạnh vật lý
và có thể chạy từng tác vụ với tốc độ chính xác như nhau, song song, mỗi
tác vụ tại tốc độ 1/nr_running. Ví dụ: nếu có 2 tác vụ đang chạy, thì nó sẽ
chạy mỗi tác vụ với 50% sức mạnh vật lý --- tức là thực sự song song.

 Trên phần cứng thực, chúng tôi chỉ có thể chạy một tác vụ duy nhất cùng
một lúc, vì vậy chúng tôi phải giới thiệu khái niệm "virtual runtime"(thời
gian chạy ảo). Thời gian chạy ảo của một tác vụ chỉ định khi nào thì khoảng
thời gian tiếp theo của nó sẽ bắt đầu thực thi trên CPU đa tác vụ lý tưởng
được mô tả ở trên. Trong thực tế, thời gian chạy ảo của một tác vụ là thời
gian chạy thực của nó được chuẩn hóa thành tổng số tác vụ đang chạy.
 Trong CFS, thời gian chạy ảo được thể hiện và theo dõi thông qua giá trị p-
>se.vruntime (đơn vị nanosec) cho mỗi tác vụ. Bằng cách này, có thể chính
xác dấu thời gian và đo "thời gian CPU dự kiến" mà một tác vụ lẽ ra phải
nhận được.

 [ small detail: trên phần cứng "lý tưởng", bất cứ lúc nào, tất cả các tác vụ sẽ
có cùng giá trị p->se.vruntime --- tức là, các tác vụ sẽ thực thi đồng thời và
không có tác vụ nào bị "mất cân bằng" so với "lý tưởng" " chia sẻ thời gian
CPU. ]

 Logic chọn tác vụ của CFS dựa trên giá trị p->se.vruntime này và do đó nó
rất đơn giản: nó luôn cố gắng chạy tác vụ với giá trị p->se.vruntime nhỏ
nhất (nghĩa là tác vụ được thực hiện ít nhất cho đến nay ). CFS luôn cố gắng
phân chia thời gian CPU giữa các tác vụ có thể chạy được càng gần với
"phần cứng đa nhiệm lý tưởng" càng tốt.

MỘT SỐ TÍNH NĂNG CỦA CFS

 CFS sử dụng tính toán chi tiết nano giây và không dựa vào bất kỳ ảnh chụp
nhanh hoặc chi tiết HZ nào khác. Do đó, bộ lập lịch CFS không có khái niệm
về "lát cắt thời gian" trong cách mà bộ lập lịch trình trước đó đã có và
không có phương pháp phỏng đoán nào. Chỉ có một điều chỉnh trung tâm
(bạn phải bật CONFIG_SCHED_DEBUG):

 /proc/sys/kernel/sched_min_granularity_ns

 có thể được sử dụng để điều chỉnh bộ lập lịch từ "máy tính để bàn" (nghĩa
là độ trễ thấp) sang "máy chủ" (tức là, tạo khối tốt ) khối lượng công việc.
Nó mặc định là một cài đặt phù hợp với khối lượng công việc trên máy tính
để bàn. SCHED_BATCH cũng được xử lý bởi mô-đun lập lịch trình CFS.
 Do thiết kế của nó, bộ lập lịch CFS không dễ bị bất kỳ "cuộc tấn công" nào
tồn tại ngày nay chống lại các chẩn đoán của bộ lập lịch chứng khoán:
fivetp.c, thud.c, nhai.c, ring-test.c, mass_intr.c tất cả đều hoạt động tốt và
không ảnh hưởng đến tính tương tác cũng như tạo ra hành vi mong đợi.

 Bộ lập lịch CFS có khả năng xử lý các cấp độ đẹp và SCHED_BATCH mạnh
mẽ hơn nhiều so với bộ lập lịch vanilla trước đó: cả hai loại khối lượng công
việc đều được tách biệt mạnh mẽ hơn nhiều.

 Cân bằng tải SMP đã được làm lại/khử trùng: các giả định chạy hàng đợi
hiện đã biến mất khỏi mã cân bằng tải và các trình vòng lặp của mô-đun lập
lịch trình được sử dụng. Kết quả là mã cân bằng trở nên đơn giản hơn một
chút .

Thiết Kế RBTree
CFS của Linux cung cấp một thuật toán hiệu quả để chọn
tác vụ nào sẽ chạy tiếp theo. Mỗi tác vụ có thể chạy được đặt trong một Red-
Black Tree – cây tìm kiếm nhị phân cân bằng có khóa dựa trên giá trị
của vruntime . 

Cây này được hiển thị dưới đây:


Khi một tác vụ có thể chạy được, nó sẽ được thêm vào cây. Nếu một tác
vụ trên cây không thể chạy được (ví dụ: nếu nó bị chặn trong khi chờ
I/O), thì nó sẽ bị xóa. Nói chung, các tác vụ có ít thời gian xử lý hơn (giá
trị nhỏ hơn của vruntime ) nằm ở phía bên trái của cây và các tác vụ
có nhiều thời gian xử lý hơn nằm ở phía bên phải.

Theo các thuộc tính của cây tìm kiếm nhị phân, nút ngoài cùng bên trái
có giá trị khóa nhỏ nhất, vì lợi ích của bộ lập lịch CFS có nghĩa là nó là
nhiệm vụ có mức độ ưu tiên cao nhất. Vì Red-Black Tree mang tính cân
bằng, điều hướng nó để khám phá nút ngoài cùng bên trái sẽ yêu cầu
các phép toán O(lgN) (trong đó N là số nút trong cây). Tuy nhiên, vì lý
do hiệu quả, bộ lập lịch Linux lưu trữ giá trị này trong
biến rb_leftmost và do đó xác định tác vụ nào sẽ chạy tiếp theo chỉ
yêu cầu truy xuất giá trị đã lưu trong bộ đệm ẩn.
Tài liệu:
https://vimentor.com/en/lesson/process-scheduling
https://www.scaler.com/topics/operating-system/process-scheduling/
https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/6_CPU_Scheduling.html

Sách Linux Programming Interface chapter 35.

Ví Dụ và cách tính:

https://viblo.asia/p/tien-trinh-trong-he-dieu-hanh-phan-3-3Q75wg6Q5Wb#_first-in-first-out-fifo-0
https://www.educative.io/answers/arrival-burst-completion-turnaround-waiting-response-time

CFS (The Linux Scheduler):


https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt
https://stackoverflow.com/questions/19181834/what-is-the-concept-of-vruntime-in-cfs
https://blog.acolyer.org/2016/04/26/the-linux-scheduler-a-decade-of-wasted-cores/

You might also like