GNU/Linux >> Belajar Linux >  >> Linux

Apa itu proses yang tidak terputus?

Ketika sebuah proses dalam mode pengguna, ia dapat diinterupsi kapan saja (beralih ke mode kernel). Ketika kernel kembali ke mode pengguna, ia memeriksa apakah ada sinyal yang tertunda (termasuk sinyal yang digunakan untuk mematikan proses, seperti SIGTERM dan SIGKILL ). Ini berarti proses hanya dapat dimatikan saat kembali ke mode pengguna.

Alasan mengapa suatu proses tidak dapat dimatikan dalam mode kernel adalah karena proses tersebut berpotensi merusak struktur kernel yang digunakan oleh semua proses lain dalam mesin yang sama (cara yang sama membunuh utas dapat berpotensi merusak struktur data yang digunakan oleh utas lain dalam proses yang sama) .

Ketika kernel perlu melakukan sesuatu yang bisa memakan waktu lama (menunggu pipa yang ditulis oleh proses lain atau menunggu perangkat keras melakukan sesuatu, misalnya), kernel tidur dengan menandai dirinya sebagai tidur dan memanggil penjadwal untuk beralih ke yang lain. proses (jika tidak ada proses non-tidur, ia beralih ke proses "tiruan" yang memberi tahu cpu untuk sedikit melambat dan duduk dalam satu lingkaran — putaran diam).

Jika sinyal dikirim ke proses tidur, itu harus dibangunkan sebelum kembali ke ruang pengguna dan dengan demikian memproses sinyal yang tertunda. Di sini kita memiliki perbedaan antara dua jenis tidur utama:

  • TASK_INTERRUPTIBLE , tidur yang terganggu. Jika sebuah tugas ditandai dengan bendera ini, tugas tersebut sedang tidur, tetapi dapat dibangunkan oleh sinyal. Ini berarti kode yang menandai tugas sebagai tidur mengharapkan sinyal yang mungkin, dan setelah bangun akan memeriksanya dan kembali dari panggilan sistem. Setelah sinyal ditangani, panggilan sistem berpotensi dimulai ulang secara otomatis (dan saya tidak akan membahas detail tentang cara kerjanya).
  • TASK_UNINTERRUPTIBLE , tidur tanpa gangguan. Jika sebuah tugas ditandai dengan flag ini, tugas tersebut tidak diharapkan dibangunkan oleh apa pun selain apa pun yang ditunggunya, baik karena tidak dapat dengan mudah dimulai ulang, atau karena program mengharapkan panggilan sistem menjadi atomik. Ini juga dapat digunakan untuk tidur yang dikenal sangat singkat.

TASK_KILLABLE (disebutkan dalam artikel LWN yang ditautkan oleh jawaban ddaa) adalah varian baru.

Ini menjawab pertanyaan pertama Anda. Mengenai pertanyaan kedua Anda:Anda tidak dapat menghindari tidur tanpa gangguan, itu adalah hal yang normal (ini terjadi, misalnya, setiap kali proses membaca/menulis dari/ke disk); namun, mereka hanya bertahan sepersekian detik. Jika mereka bertahan lebih lama, itu biasanya berarti masalah perangkat keras (atau masalah driver perangkat, yang terlihat sama dengan kernel), di mana driver perangkat sedang menunggu perangkat keras untuk melakukan sesuatu yang tidak akan pernah terjadi. Ini juga bisa berarti Anda menggunakan NFS dan server NFS tidak aktif (sedang menunggu server pulih; Anda juga dapat menggunakan opsi "intr" untuk menghindari masalah).

Terakhir, alasan Anda tidak dapat memulihkan adalah alasan yang sama dengan kernel menunggu hingga kembali ke mode pengguna untuk mengirimkan sinyal atau mematikan proses:ini berpotensi merusak struktur data kernel (kode yang menunggu saat tidur yang dapat diinterupsi dapat menerima kesalahan yang memberitahukannya untuk kembali ke ruang pengguna, tempat proses dapat dihentikan; kode yang menunggu pada mode tidur yang tidak dapat terputus tidak mengharapkan kesalahan apa pun).


Proses yang tidak dapat terputus BIASANYA menunggu I/O mengikuti kesalahan halaman.

Pertimbangkan ini:

  • Utas mencoba untuk mengakses halaman yang tidak dalam inti (baik yang dapat dieksekusi yang dimuat permintaan, halaman memori anonim yang telah ditukar, atau file mmap()'d yang dimuat permintaan, yang banyak hal yang sama)
  • Kernel sekarang (mencoba) memuatnya
  • Proses tidak dapat dilanjutkan sampai halaman tersedia.

Proses/tugas tidak dapat diinterupsi dalam keadaan ini, karena tidak dapat menangani sinyal apa pun; jika ya, kesalahan halaman lain akan terjadi dan akan kembali seperti semula.

Ketika saya mengatakan "proses", maksud saya sebenarnya adalah "tugas", yang di Linux (2.6) secara kasar diterjemahkan menjadi "utas" yang mungkin atau mungkin tidak memiliki entri "grup utas" individual di /proc

Dalam beberapa kasus, mungkin menunggu lama. Contoh tipikal dari hal ini adalah di mana file yang dapat dieksekusi atau file mmap berada di sistem file jaringan tempat server gagal. Jika I/O akhirnya berhasil, tugas akan dilanjutkan. Jika akhirnya gagal, tugas umumnya akan mendapatkan SIGBUS atau semacamnya.


Proses yang tidak dapat terputus adalah proses yang terjadi dalam panggilan sistem (fungsi kernel) yang tidak dapat diinterupsi oleh sinyal.

Untuk memahami apa artinya, Anda perlu memahami konsep panggilan sistem yang dapat diinterupsi. Contoh klasiknya adalah read() . Ini adalah panggilan sistem yang dapat memakan waktu lama (detik) karena berpotensi melibatkan pemutaran hard drive, atau pemindahan kepala. Selama sebagian besar waktu ini, proses akan tidur, memblokir perangkat keras.

Saat proses tidur dalam panggilan sistem, proses tersebut dapat menerima sinyal asinkron Unix (katakanlah, SIGTERM), lalu hal berikut terjadi:

  • Panggilan sistem keluar sebelum waktunya, dan diatur untuk mengembalikan -EINTR ke ruang pengguna.
  • Pengendali sinyal dijalankan.
  • Jika proses masih berjalan, ia mendapatkan nilai kembalian dari panggilan sistem, dan dapat melakukan panggilan yang sama lagi.

Kembali lebih awal dari panggilan sistem memungkinkan kode ruang pengguna untuk segera mengubah perilakunya sebagai respons terhadap sinyal. Misalnya, menghentikan secara bersih sebagai reaksi terhadap SIGINT atau SIGTERM.

Di sisi lain, beberapa panggilan sistem tidak boleh diinterupsi dengan cara ini. Jika sistem memanggil kios karena alasan tertentu, prosesnya dapat tetap dalam keadaan tidak dapat dimatikan ini tanpa batas waktu.

LWN memuat artikel bagus yang menyentuh topik ini di bulan Juli.

Untuk menjawab pertanyaan awal:

  • Cara mencegah hal ini terjadi:cari tahu driver mana yang menyebabkan masalah bagi Anda, dan berhenti menggunakan, atau menjadi peretas kernel dan memperbaikinya.

  • Cara mematikan proses yang tidak dapat terputus tanpa me-reboot:entah bagaimana membuat panggilan sistem berhenti. Seringkali cara paling efektif untuk melakukan ini tanpa menekan tombol daya adalah dengan menarik kabel daya. Anda juga bisa menjadi peretas kernel dan membuat driver menggunakan TASK_KILLABLE, seperti yang dijelaskan di artikel LWN.


Untuk pertanyaan ke-3 Anda:Saya pikir Anda dapat mematikan proses yang tidak dapat terputus dengan menjalankan sudo kill -HUP 1 .Ini akan memulai ulang init tanpa mengakhiri proses yang berjalan dan setelah menjalankannya, proses saya yang tidak dapat terputus hilang.


Linux
  1. Proses Apa yang Membuat Jendela X11 Ini?

  2. Apa Penyebab Berbagai Sinyal Terkirim?

  3. Memulai Proses Pada Tty yang Berbeda?

  1. Proses apa yang menggunakan semua IO disk saya

  2. Apa yang terjadi ketika sebuah benang bercabang?

  3. Proses mana yang memakan ptys di server Linux saya?

  1. Apa definisi sesi di linux?

  2. Apa perintah untuk menemukan prioritas proses di Linux?

  3. Tentukan di grup mana proses berjalan berada?