103.6 Bài 1
Chứng chỉ: |
LPIC-1 |
---|---|
Phiên bản: |
5.0 |
Chủ đề: |
103 Lệnh GNU và Unix |
Mục tiêu: |
103.6 Sửa đổi Ưu tiên thực hiện Tiến trình |
Bài: |
1 trên 1 |
Giới thiệu
Các hệ điều hành có thể chạy nhiều tiến trình cùng một lúc được gọi là hệ thống đa nhiệm hoặc đa xử lý. Trong khi tính đồng thời thực sự chỉ xảy ra khi có sẵn nhiều đơn vị xử lý thì ngay cả các hệ thống bộ xử lý đơn lẻ cũng có thể bắt chước được tính đồng thời này bằng cách chuyển đổi thật nhanh giữa các tiến trình. Kỹ thuật này cũng được sử dụng trong các hệ thống có nhiều CPU tương đương hoặc hệ thống đa bộ xử lý đối xứng (SMP), với điều kiện là số lượng tiến trình đồng thời tiềm năng phải vượt xa số lượng đơn vị bộ xử lý có sẵn.
Trên thực tế, chỉ có một tiến trình có thể điều khiển CPU tại một thời điểm nhất định. Tuy nhiên, hầu hết các hoạt động của tiến trình là các lời gọi hệ thống, nghĩa là tiến trình đang chạy sẽ chuyển quyền kiểm soát CPU sang tiến trình của hệ điều hành để nó thực hiện thao tác được yêu cầu. Các phiên gọi hệ thống sẽ phụ trách tất cả các giao tiếp giữa các thiết bị như phân bổ bộ nhớ, đọc và ghi trên hệ thống tệp, in văn bản trên màn hình, tương tác người dùng, chuyển mạng, v.v. Việc chuyển quyền điều khiển CPU trong khi gọi hệ thống cho phép hệ điều hành quyết định sẽ trả lại quyền kiểm soát CPU cho tiến trình trước đó hay trao nó cho một tiến trình khác. Vì các CPU hiện đại có thể thực thi các lệnh nhanh hơn nhiều so với tốc độ giao tiếp của các phần cứng ngoại vi với nhau, một tiến trình kiểm soát mới có thể thực hiện nhiều công việc của CPU trong khi các phản hồi phần cứng được yêu cầu trước đó vẫn chưa khả dụng. Để đảm bảo khai thác tối đa CPU, các hệ điều hành đa xử lý sẽ giữ một danh sách động gồm các tiến trình đang hoạt động chờ tới "lượt" để sử dụng CPU. Mặc dù chúng cho phép cải thiện đáng kể thời gian sử dụng CPU nhưng nếu chỉ dựa vào lời gọi hệ thống để chuyển đổi giữa các tiến trình thì hiệu suất đa nhiệm sẽ không đạt được một cách thỏa đáng. Một tiến trình không thực hiện lời gọi hệ thống nào có thể kiểm soát CPU vô thời hạn. Đây là lý do tại sao các hệ điều hành hiện đại cũng mang tính ưu tiên, nghĩa là một tiến trình đang chạy có thể được đưa trở lại hàng đợi để một tiến trình quan trọng hơn có thể kiểm soát CPU ngay cả khi tiến trình đang chạy đó chưa thực hiện một lời gọi hệ thống nào.
Trình Lập Lịch Biểu Linux
Với tư cách là một hệ điều hành đa xử lý mang tính ưu tiên, Linux có triển khai một trình lập lịch biểu (Linux Scheduler) để tổ chức hàng đợi dành cho các tiến trình. Chính xác hơn, trình lập lịch biểu cũng quyết định xem luồng đang xếp hàng đợi nào sẽ được thực thi — một tiến trình có thể phân nhánh ra nhiều luồng độc lập. Tuy nhiên, tiến trình và luồng là các thuật ngữ có thể hoán đổi cho nhau trong ngữ cảnh này. Mọi tiến trình đều có hai thuộc tính can thiệp vào việc lập lịch biểu của nó: chính sách lập lịch biểu và ưu tiên lập lịch biểu.
Có hai loại chính sách lập lịch biểu chính: chính sách thời gian thực và chính sách thông thường. Các tiến trình theo chính sách thời gian thực sẽ được lên lịch trực tiếp theo các giá trị ưu tiên của chúng. Nếu một tiến trình quan trọng hơn đã sẵn sàng chạy, một tiến trình đang chạy ít quan trọng hơn sẽ phải "nhường" và tiến trình có mức ưu tiên cao hơn sẽ kiểm soát CPU. Một tiến trình có mức ưu tiên thấp hơn sẽ chỉ giành được quyền kiểm soát CPU nếu các tiến trình có mức ưu tiên cao hơn không hoạt động hoặc đang chờ phản hồi của phần cứng.
Bất kỳ tiến trình thời gian thực nào cũng có mức độ ưu tiên cao hơn một tiến trình thông thường. Là một hệ điều hành có mục đích phổ thông, Linux chỉ chạy một vài tiến trình thời gian thực. Hầu hết các tiến trình (bao gồm cả chương trình hệ thống và người dùng) đều chạy theo các chính sách lập lịch biểu thông thường. Các tiến trình thông thường thường có cùng một giá trị ưu tiên, nhưng các chính sách thông thường có thể xác định các quy tắc ưu tiên thực thi bằng cách sử dụng một thuộc tính từ tiến trình khác là giá trị nice. Để tránh nhầm lẫn với các ưu tiên động bắt nguồn từ các giá trị nice, các ưu tiên lập lịch biểu thường được gọi là các ưu tiên lập lịch biểu tĩnh.
Trình lập lịch biểu Linux có thể được cấu hình theo nhiều cách khác nhau và thậm chí còn có nhiều cách phức tạp hơn để thiết lập mức độ ưu tiên, nhưng những khái niệm cơ bản này vẫn sẽ luôn được áp dụng. Khi kiểm tra và điều chỉnh tiến trình lập lịch biểu, điều quan trọng cần lưu ý là chỉ các tiến trình theo chính sách lập lịch biểu thông thường mới bị ảnh hưởng.
Ưu tiên Đọc
Linux dành các mức độ ưu tiên tĩnh từ 0 đến 99 cho các tiến trình thời gian thực và các tiến trình bình thường được gán cho các mức độ ưu tiên tĩnh từ 100 đến 139, nghĩa là có 39 mức độ ưu tiên khác nhau cho các tiến trình thông thường. Giá trị thấp hơn có nghĩa là ưu tiên cao hơn. Mức độ ưu tiên tĩnh của một tiến trình đang hoạt động có thể được tìm thấy trong tệp sched
nằm trong thư mục tương ứng của nó bên trong hệ thống tệp /proc
:
$ grep ^prio /proc/1/sched prio : 120
Như được minh họa trong ví dụ, dòng bắt đầu bằng prio
đã đưa ra giá trị ưu tiên của tiến trình (tiến trình PID 1 là tiến trình init hoặc systemd - tiến trình đầu tiên mà hạt nhân khởi động trong quá trình khởi tạo hệ thống). Mức ưu tiên tiêu chuẩn cho các tiến trình thông thường là 120; do đó, nó có thể giảm xuống 100 hoặc tăng lên 139. Ta có thể xác minh mức độ ưu tiên của tất cả các tiến trình đang chạy bằng lệnh ps -Al
hoặc ps -el
:
$ ps -el F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 9292 - ? 00:00:00 systemd 4 S 0 19 1 0 80 0 - 8817 - ? 00:00:00 systemd-journal 4 S 104 61 1 0 80 0 - 64097 - ? 00:00:00 rsyslogd 4 S 0 63 1 0 80 0 - 7244 - ? 00:00:00 cron 1 S 0 126 1 0 80 0 - 4031 - ? 00:00:00 dhclient 4 S 0 154 1 0 80 0 - 3937 - pts/0 00:00:00 agetty 4 S 0 155 1 0 80 0 - 3937 - pts/1 00:00:00 agetty 4 S 0 156 1 0 80 0 - 3937 - pts/2 00:00:00 agetty 4 S 0 157 1 0 80 0 - 3937 - pts/3 00:00:00 agetty 4 S 0 158 1 0 80 0 - 3937 - console 00:00:00 agetty 4 S 0 160 1 0 80 0 - 16377 - ? 00:00:00 sshd 4 S 0 280 0 0 80 0 - 5301 - ? 00:00:00 bash 0 R 0 392 280 0 80 0 - 7221 - ? 00:00:00 ps
Cột PRI
cho biết mức độ ưu tiên tĩnh được chỉ định bởi hạt nhân. Tuy nhiên, hãy lưu ý rằng giá trị ưu tiên được hiển thị bởi ps
khác với giá trị thu được trong ví dụ trước. Vì nhiều lý do tiền lệ, mức độ ưu tiên được hiển thị theo ps
sẽ nằm trong khoảng từ -40 đến 99 theo mặc định. Do đó, mức độ ưu tiên thực tế được tính bằng cách cộng 40 vào mức đó (cụ thể là 80 + 40 = 120).
Chúng ta cũng có thể theo dõi liên tục các tiến trình hiện đang được quản lý bởi nhân Linux bằng chương trình top
. Như với ps
, top
cũng hiển thị giá trị ưu tiên theo một cách riêng. Để giúp xác định các tiến trình thời gian thực dễ dàng hơn, top
sẽ trừ giá trị ưu tiên đi 100, từ đó làm cho tất cả các ưu tiên thời gian thực trở thành số âm với một số âm hoặc ký tự rt để xác định chúng. Do đó, mức độ ưu tiên thông thường được hiển thị theo top
có phạm vi từ 0 đến 39.
Note
|
Để biết thêm chi tiết từ lệnh $ ps -e -o user,uid,comm,tty,pid,ppid,pri,pmem,pcpu --sort=-pcpu | head |
Độ "Nice" của Quy Trình
Mỗi một tiến trình bình thường đều bắt đầu với giá trị nice mặc định là 0 (ưu tiên 120). Cái tên nice xuất phát từ ý tưởng rằng các tiến trình “tốt bụng hơn” sẽ cho phép các tiến trình khác chạy trước chúng trong một hàng đợi thực thi. Số nice nằm trong khoảng từ -20 (ít nice, ưu tiên cao) đến 19 (nice hơn, ưu tiên thấp). Linux cũng cho phép ta gán các giá trị nice khác nhau cho các luồng trong cùng một tiến trình. Cột NI
trong đầu ra ps
cho biết giá trị nice bằng số.
Chỉ siêu người dùng mới có thể giảm mức độ nice của tiến trình xuống dưới 0. Ta có thể bắt đầu một tiến trình với mức độ ưu tiên không chuẩn bằng lệnh nice
. Theo mặc định, nice
sẽ thay đổi mức độ thành 10, nhưng nó cũng có thể được chỉ định bằng tùy chọn -n
:
$ nice -n 15 tar czf home_backup.tar.gz /home
Trong ví dụ này, lệnh tar
được thực thi với độ chính xác là 15. Lệnh renice
có thể được sử dụng để thay đổi mức độ ưu tiên của một tiến trình đang chạy. Tùy chọn -p
sẽ cho biết số PID của tiến trình đích. Ví dụ:
# renice -10 -p 2164 2164 (process ID) old priority 0, new priority -10
Các tùy chọn -g
và -u
được sử dụng để sửa đổi tương ứng tất cả các tiến trình của một nhóm hoặc một người dùng cụ thể. Với renice +5 -g users
, tính nice của các tiến trình do người dùng của nhóm users sở hữu sẽ được nâng lên năm lần.
Bên cạnh renice
, mức độ ưu tiên của các tiến trình có thể được sửa đổi bằng các chương trình khác như top
. Trên màn hình chính trên cùng, độ chuẩn của tiến trình có thể được sửa đổi bằng cách nhấn r
và sau đó là số PID của tiến trình:
top - 11:55:21 up 23:38, 1 user, load average: 0,10, 0,04, 0,05 Tasks: 20 total, 1 running, 19 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,5 us, 0,3 sy, 0,0 ni, 99,0 id, 0,0 wa, 0,2 hi, 0,0 si, 0,0 st KiB Mem : 4035808 total, 774700 free, 1612600 used, 1648508 buff/cache KiB Swap: 7999828 total, 7738780 free, 261048 used. 2006688 avail Mem PID to renice [default pid = 1] PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 74232 7904 6416 S 0,000 0,196 0:00.12 systemd 15 root 20 0 67436 6144 5568 S 0,000 0,152 0:00.03 systemd-journal 21 root 20 0 61552 5628 5000 S 0,000 0,139 0:00.01 systemd-logind 22 message+ 20 0 43540 4072 3620 S 0,000 0,101 0:00.03 dbus-daemon 23 root 20 0 45652 6204 4992 S 0,000 0,154 0:00.06 wickedd-dhcp4 24 root 20 0 45648 6276 5068 S 0,000 0,156 0:00.06 wickedd-auto4 25 root 20 0 45648 6272 5060 S 0,000 0,155 0:00.06 wickedd-dhcp6
Thông báo PID to renice [default pid = 1]
sẽ xuất hiện với tiến trình được liệt kê đầu tiên được chọn theo mặc định. Để thay đổi mức độ ưu tiên của một tiến trình khác, hãy nhập PID của tiến trình đó rồi nhấn Enter. Sau đó, thông báo Renice PID 1 to value
sẽ xuất hiện (với số PID được yêu cầu) và ta có thể gán một giá trị nice mới.
Bài tập Hướng dẫn
-
Trong một hệ thống đa nhiệm mang tính ưu tiên, điều gì sẽ xảy ra khi một tiến trình có mức ưu tiên thấp hơn đang chiếm bộ xử lý và một tiến trình có mức ưu tiên cao hơn đang được xếp hàng để đợi được thực thi?
-
Hãy xem màn hình
top
sau:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
PID nào có ưu tiên thời gian thực?
-
Hãy xem danh sách
ps -el
sau:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
PID nào có mức ưu tiên cao hơn?
-
Sau khi cố gắng đặt lại giá trị nice cho một tiến trình với
renice
, lỗi sau đã xảy ra:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Nguyên nhân gây ra lỗi này là gì?
Bài tập Mở rộng
-
Việc thay đổi mức độ ưu tiên của tiến trình thường được yêu cầu khi một tiến trình chiếm quá nhiều thời gian của CPU. Khi sử dụng
ps
với các tùy chọn tiêu chuẩn để in tất cả các tiến trình hệ thống ở định dạng dài, cờ--sort
nào sẽ sắp xếp các tiến trình theo mức sử dụng CPU theo thứ tự tăng dần? -
Lệnh
schedtool
có khả năng đặt tất cả các tham số lập lịch biểu CPU mà Linux có khả năng thực thi hoặc hiển thị thông tin cho các tiến trình nhất định. Làm thế nào để nó có thể được sử dụng để hiển thị các tham số lập lịch biểu của tiến trình1750
? Ngoài ra, làm cách nào để sử dụngschedtool
để thay đổi tiến trình 1750 thành tiến trình thời gian thực với mức độ ưu tiên -90 (như được hiển thị bởitop
)?
Tóm tắt
Bài học này đã trình bày cách Linux phân bổ thời gian của CPU cho các tiến trình nó quản lý. Để đảm bảo hiệu suất tốt nhất, các tiến trình quan trọng hơn phải vượt qua các tiến trình ít quan trọng hơn. Bài học đã đi qua các bước sau:
-
Các khái niệm cơ bản về hệ thống đa xử lý.
-
Trình lập lịch biểu tiến trình là gì và cách Linux triển khai nó.
-
Ưu tiên của Linux là gì, giá trị "nice" và mục đích của chúng.
-
Cách đọc và giải thích các ưu tiên của tiến trình trong Linux.
-
Cách thay đổi mức độ ưu tiên của một tiến trình trước và trong khi thực hiện.
Đáp án Bài tập Hướng dẫn
-
Trong một hệ thống đa nhiệm mang tính ưu tiên, điều gì sẽ xảy ra khi một tiến trình có mức ưu tiên thấp hơn đang chiếm bộ xử lý và một tiến trình có mức ưu tiên cao hơn đang được xếp hàng để đợi được thực thi?
Quá trình có mức ưu tiên thấp hơn sẽ tạm dừng và thay vào đó, quá trình có mức độ ưu tiên cao hơn sẽ được thực thi.
-
Hãy xem màn hình
top
sau:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
PID nào có ưu tiên thời gian thực?
PIDs 12 và 16.
-
Hãy xem danh sách
ps -el
sau:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
PID nào có mức ưu tiên cao hơn?
PID 12.
-
Sau khi cố gắng đặt lại giá trị nice cho một tiến trình với
renice
, lỗi sau đã xảy ra:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Nguyên nhân gây ra lỗi này là gì?
Chỉ siêu người dùng mới có thể giảm các số chuẩn xuống dưới 0.
Đáp án Bài tập Mở rộng
-
Việc thay đổi mức độ ưu tiên của tiến trình thường được yêu cầu khi một tiến trình chiếm quá nhiều thời gian của CPU. Khi sử dụng
ps
với các tùy chọn tiêu chuẩn để in tất cả các tiến trình hệ thống ở định dạng dài, cờ--sort
nào sẽ sắp xếp các tiến trình theo mức sử dụng CPU theo thứ tự tăng dần?$ ps -el --sort=pcpu
-
Lệnh
schedtool
có khả năng đặt tất cả các tham số lập lịch biểu CPU mà Linux có khả năng thực thi hoặc hiển thị thông tin cho các tiến trình nhất định. Làm thế nào để nó có thể được sử dụng để hiển thị các tham số lập lịch biểu của tiến trình1750
? Ngoài ra, làm cách nào để sử dụngschedtool
để thay đổi tiến trình 1750 thành tiến trình thời gian thực với mức độ ưu tiên -90 (như được hiển thị bởitop
)?$ schedtool 1750
$ schedtool -R -p 89 1750