GNU/Linux >> Belajar Linux >  >> Linux

Dasar-Dasar Sinyal Linux – Bagian I

Apa itu sinyal? Sinyal adalah interupsi perangkat lunak.

Program yang kuat perlu menangani sinyal. Ini karena sinyal adalah cara untuk mengirimkan peristiwa asinkron ke aplikasi.

Pengguna menekan ctrl+c, proses mengirim sinyal untuk mematikan proses lain, dll. adalah semua kasus di mana suatu proses perlu melakukan penanganan sinyal.

Sinyal Linux

Di Linux, setiap sinyal memiliki nama yang diawali dengan karakter SIG. Misalnya :

  • Sinyal SIGINT yang dihasilkan saat pengguna menekan ctrl+c. Ini adalah cara untuk menghentikan program dari terminal.
  • SIGALRM  dihasilkan saat timer yang disetel oleh fungsi alarm mati.
  • Sinyal SIGABRT dihasilkan saat sebuah proses memanggil fungsi abort.
  • dll

Ketika sinyal muncul, proses harus memberi tahu kernel apa yang harus dilakukan dengannya. Ada tiga opsi yang dapat digunakan untuk membuang sinyal :

  1. Sinyal dapat diabaikan. Dengan mengabaikan kami berarti bahwa tidak ada yang akan dilakukan ketika sinyal terjadi. Sebagian besar sinyal dapat diabaikan tetapi sinyal yang dihasilkan oleh pengecualian perangkat keras seperti membagi dengan nol, jika diabaikan dapat memiliki konsekuensi yang aneh. Selain itu, beberapa sinyal seperti SIGKILL dan SIGSTOP tidak dapat diabaikan.
  2. Sinyalnya bisa ditangkap. Ketika opsi ini dipilih, maka proses mendaftarkan fungsi dengan kernel. Fungsi ini dipanggil oleh kernel ketika sinyal itu muncul. Jika sinyal tidak fatal untuk proses maka dalam fungsi tersebut proses dapat menangani sinyal dengan baik atau sebaliknya dapat memilih untuk mengakhiri dengan anggun.
  3. Biarkan tindakan default berlaku. Setiap sinyal memiliki tindakan default. Ini bisa berupa penghentian proses, abaikan, dll.

Seperti yang telah kami nyatakan bahwa dua sinyal SIGKILL dan SIGSTOP tidak dapat diabaikan. Ini karena kedua sinyal ini menyediakan cara bagi pengguna root atau kernel untuk mematikan atau menghentikan proses apa pun dalam situasi apa pun. Tindakan default dari sinyal ini adalah menghentikan proses. Sinyal ini tidak dapat ditangkap atau diabaikan.

Apa yang Terjadi pada Program Start-up?

Itu semua tergantung pada proses yang memanggil exec. Saat proses dimulai, status semua sinyal diabaikan atau default. Opsi selanjutnya yang lebih mungkin terjadi kecuali proses yang memanggil exec mengabaikan sinyal.

Ini adalah properti fungsi exec untuk mengubah tindakan pada sinyal apa pun menjadi tindakan default. Dalam istilah yang lebih sederhana, jika induk memiliki fungsi penangkapan sinyal yang dipanggil pada kemunculan sinyal maka jika induk tersebut menjalankan proses anak baru, maka fungsi ini tidak memiliki arti dalam proses baru dan karenanya disposisi sinyal yang sama disetel ke default dalam proses baru.

Juga, Karena kami biasanya memiliki proses yang berjalan di latar belakang sehingga shell hanya menetapkan disposisi sinyal keluar sebagai diabaikan karena kami tidak ingin proses latar belakang dihentikan oleh pengguna yang menekan tombol ctrl+c karena itu mengalahkan tujuan membuat suatu proses berjalan di latar belakang.

Mengapa Fungsi Penangkap Sinyal harus Masuk Kembali?

Seperti yang telah kita bahas bahwa salah satu opsi untuk disposisi sinyal adalah menangkap sinyal. Dalam kode proses ini dilakukan dengan mendaftarkan fungsi ke kernel yang dipanggil kernel ketika sinyal muncul. Satu hal yang harus diingat adalah bahwa fungsi yang didaftarkan oleh proses harus masuk kembali.

Sebelum menjelaskan alasannya, mari kita pahami dulu apa itu fungsi reentrant? Fungsi reentrant adalah fungsi yang eksekusinya dapat dihentikan di antaranya karena alasan apa pun (seperti karena interupsi atau sinyal) dan kemudian dapat dimasukkan kembali dengan aman sebelum pemanggilan sebelumnya menyelesaikan eksekusi.

Sekarang kembali ke masalah, Misalkan fungsi func() terdaftar untuk panggilan balik pada kemunculan sinyal. Sekarang asumsikan bahwa func() ini sudah dalam eksekusi saat sinyal muncul. Karena fungsi ini dipanggil kembali untuk sinyal ini, maka eksekusi saat ini pada sinyal ini akan dihentikan oleh penjadwal dan fungsi ini akan dipanggil lagi (karena sinyal).

Masalahnya bisa jika func() bekerja pada beberapa nilai global atau struktur data yang dibiarkan dalam keadaan tidak konsisten ketika eksekusi fungsi ini dihentikan di tengah, maka panggilan kedua ke fungsi yang sama (karena sinyal) dapat menyebabkan beberapa hasil yang tidak diinginkan.

Jadi kami katakan bahwa fungsi penangkapan sinyal harus dibuat masuk kembali.

Lihat artikel kami kirim-sinyal-ke-proses dan perintah fuser Linux untuk melihat contoh praktis tentang cara mengirim sinyal ke suatu proses.

Utas dan Sinyal

Kita telah melihat di salah satu bagian sebelumnya bahwa penanganan sinyal datang dengan sedikit kerumitannya sendiri (seperti menggunakan fungsi reentrant). Untuk menambah kerumitan, kami biasanya memiliki aplikasi multi-ulir di mana penanganan sinyal menjadi sangat rumit.

Setiap utas memiliki topeng sinyal pribadinya sendiri (masker yang menentukan sinyal mana yang dapat dikirim) tetapi cara disposisi sinyal dilakukan dibagikan oleh semua utas dalam aplikasi. Ini berarti bahwa disposisi untuk sinyal tertentu yang ditetapkan oleh utas dapat dengan mudah ditolak oleh utas lainnya. Dalam hal ini mekanisme disposisi berubah untuk semua utas.

Misalnya, thread A dapat memilih untuk mengabaikan sinyal tertentu tetapi thread B dalam proses yang sama dapat memilih untuk menangkap sinyal yang sama dengan mendaftarkan fungsi callback ke kernel. Dalam hal ini permintaan yang dibuat oleh utas A ditolak oleh permintaan utas B.

Sinyal dikirim hanya ke satu utas dalam proses apa pun. Terlepas dari pengecualian perangkat keras atau penghitung waktu kedaluwarsa (yang dikirimkan ke utas yang menyebabkan peristiwa tersebut) semua sinyal diteruskan ke proses secara sewenang-wenang.

Untuk mengatasi kekurangan ini ada beberapa API posix seperti pthread_sigmask() dll yang dapat digunakan.

Pada artikel berikutnya (bagian 2) dari seri ini, kita akan membahas tentang cara menangkap sinyal dalam suatu proses, dan menjelaskan aspek praktis penanganan sinyal menggunakan cuplikan kode.


Linux
  1. UNIX / Linux:3 Cara Mengirim Sinyal ke Proses

  2. Pengantar Utas Linux – Bagian I

  3. Kapan setsid() berguna, atau mengapa kita perlu mengelompokkan proses di Linux?

  1. Pengantar Dasar-dasar Perutean IP Linux (Bagian 1)

  2. IPC menggunakan Sinyal di linux

  3. Membuat daemon di Linux

  1. Proses Boot Linux

  2. Status Proses Linux

  3. Proses Pembuatan Linux?