Satu inti CPU hanya bisa mengeksekusi satu proses pada satu saat, padahal sistem yang ramai menjalankan ratusan proses sekaligus. Yang memutuskan siapa yang kebagian giliran adalah scheduler di dalam kernel. Setelah kita bisa melihat dan menghentikan proses, pertanyaan berikutnya menyangkut urutan: bisakah kita memberi tahu kernel bahwa sebuah proses lebih — atau kurang — penting dari yang lain? Chapter ini membahas tiga konsep penopangnya — nice value, prioritas dinamis, dan load average — sebelum kita berlatih mengubahnya dengan nice dan renice.

Scheduler CPU dan Pembagian Giliran Waktu #

Kernel membagi waktu CPU menjadi potongan kecil bernama time slice, lalu berganti proses begitu potongan itu habis — peristiwanya disebut context switch. Scheduler Linux modern mencatat berapa lama tiap proses memakai CPU lewat angka virtual runtime, lalu mengutamakan proses yang angkanya paling tertinggal. Prinsip “yang paling jarang kebagian naik ke depan” inilah yang membuat editor dan browser tetap responsif meski kompilasi besar berlangsung di background.

Nice value adalah tuas untuk menggeser pembagian itu: nice rendah berarti porsi CPU lebih besar, nice tinggi berarti porsi lebih kecil. Scheduler tetap menjalankan semuanya — yang berubah hanyalah besar porsinya.

Nice Value: Skala Kebaikan dari -20 sampai 19 #

Nice value berkisar dari -20 (prioritas tertinggi) hingga 19 (prioritas terendah), dengan nilai bawaan 0 untuk setiap proses baru. Arah skalanya memang kebalik dari intuisi: semakin rendah angkanya, semakin rakus proses itu terhadap CPU. Nama “nice” sendiri memang harfiah — proses yang dijalankan dengan nice -n 10 sedang bersikap sopan kepada proses lain karena rela mengalah.

Nilai niceArti bagi proses
-20prioritas tertinggi; hanya root yang boleh memasangnya
0nilai bawaan semua proses baru
10proses bersikap sopan; cocok untuk pekerjaan background
19prioritas terendah; hanya jalan saat CPU nyaris menganggur

Mari kita buktikan bahwa angka ini benar-benar menempel pada proses, bukan sekadar teori. Blok berikut membaca nice milik shell itu sendiri, melahirkan sebuah sleep dengan nice 10, lalu membaca kembali nilainya:

bash
echo "nice shell ini  : $(ps -o ni= -p $$ | tr -d ' ')"
nice -n 10 sleep 30 &
pid=$!
echo "nice sleep baru  : $(ps -o ni= -p "$pid" | tr -d ' ')"
kill "$pid"

Output yang Dihasilkan:

text
nice shell ini  : 0
nice sleep baru  : 10

Mari kita telaah blok di atas:

  1. Baris 1 (echo ... ps -o ni= -p $$): membaca kolom NI milik shell yang menjalankan blok; tanda = pada ni= menyembunyikan header kolom.
  2. Baris 2-3 (nice -n 10 sleep 30 & dan pid=$!): melahirkan proses sleep dengan nice 10 di background lalu menangkap PID-nya ke variabel — PID tidak dicetak karena nilainya berbeda tiap eksekusi.
  3. Baris 4 (echo ... ps -o ni= -p "$pid"): membaca kembali nilai NI proses sleep, dan terbukti 10 — nice yang diminta saat kelahiran benar-benar dipakai kernel.
  4. Baris 5 (kill "$pid"): membereskan proses percobaan.

Sekarang kita uji batas izinnya. Blok berikut mencoba melahirkan proses dengan nice negatif:

bash
nice -n -5 true 2>&1
echo "exit=$?"

Output yang Dihasilkan:

text
nice: cannot set niceness: Permission denied
exit=0

Apa yang terjadi: nice -n -5 meminta prioritas di atas bawaan, dan kernel menolaknya karena user biasa hanya boleh menaikkan angka nice — artinya menurunkan prioritasnya sendiri. Menurunkan angka nice, termasuk memasang nilai negatif, membutuhkan root melalui sudo nice -n -5 .... Dua detail pada blok itu: pesan penolakan dikirim ke stderr lalu dialirkan ke stdout dengan 2>&1 agar ikut terverifikasi, dan exit=0 karena nice tetap menjalankan true dengan nice bawaan meski permintaannya ditolak.

Prioritas Dinamis vs Nice Statis #

Nilai nice bersifat statis: angkanya bertahan selama proses hidup dan hanya berubah bila seseorang menjalankan renice. Kernel kemudian menghitung prioritas efektif dari nilai statis ini ditambah penyesuaian dinamis — misalnya proses interaktif yang lama menunggu masukan mendapat dorongan agar tetap responsif. Angka hasil perhitungan itulah yang tampil di kolom PR pada ps dan top, sedangkan kolom NI selalu menampilkan nilai statis yang kita atur. Sebagai gambaran, proses user biasa dengan nice 0 umumnya tampil PR 20, dan nice 10 tampil PR 30 — prioritas dinamis untuk proses biasa kira-kira 20 + NI.

Praktik yang sehat: gunakan nice untuk pekerjaan batch yang menghabiskan CPU lama — kompresi, kompilasi, konversi video — dan biarkan kernel mengurus penyesuaian dinamisnya.

Load Average: Termometer Antrean CPU #

Nice mengatur satu proses; load average memberi tahu keadaan seluruh sistem. Angka ini adalah rata-rata jumlah proses yang sedang berjalan atau menunggu giliran CPU — termasuk yang terjebak menunggu I/O — untuk jendela 1, 5, dan 15 menit terakhir, dibaca dari baris pertama top atau dari uptime. Berikut contoh tampilan top pada sistem yang sedang sibuk ringan:

text
top - 14:32:07 up  5:12,  2 users,  load average: 0.52, 0.48, 0.41
Tasks: 214 total,   1 running, 213 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.1 us,  1.2 sy,  0.0 ni, 95.4 id,  0.2 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :  15914.0 total,   9120.3 free,   2811.2 used,   2982.5 buff/cache

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1428 budi      20   0 4613124 310512 124800 S   4.2   1.9  12:45.92 firefox
 1901 budi      30  10 1230400  88120  15120 S   0.3   0.5   0:41.20 makemkv

Tiga angka setelah load average: adalah urutan 1, 5, dan 15 menit — 0.52 → 0.48 → 0.41 berarti beban sedang menurun setelah sempat naik. Patokannya bukan angka mutlak melainkan jumlah inti CPU: load 2.0 di mesin 8 inti masih santai, di mesin 1 inti berarti antrean menumpuk; jumlah inti dicek dengan nproc. Perhatikan juga kolom PR dan NI: makemkv dengan nice 10 tampil prioritas dinamis 30, persis pola 20 + NI di atas.

Sumber data load average adalah file /proc/loadavg yang bisa dibaca langsung. Isinya satu baris dengan lima kolom — berikut contoh tampilannya:

text
0.52 0.48 0.41 2/214 14290

Tiga angka pertama adalah load average 1/5/15 menit. Kolom keempat, 2/214, berarti 2 proses berjalan dari total 214; kolom terakhir adalah PID yang paling baru dilahirkan — terus berganti setiap saat, itulah sebabnya formatnya kita jelaskan di sini tanpa menjadikan nilainya contoh tetap. Struktur file ini didokumentasikan di proc(5) , model penjadwalan CPU di sched(7) .

Kini kita tahu bahwa kolom NI adalah tuas yang bisa digeser dan load average adalah alat ukurnya. Pertanyaan berikutnya praktis: bagaimana cara menggesernya, sebelum proses berjalan dan setelahnya? Materi Chapter nice dan renice menjawab keduanya.