Isyarat
Isyarat adalah peristiwa yang dihasilkan untuk memberitahu proses atau utas bahawa beberapa situasi penting telah tiba. Apabila proses atau utas telah menerima isyarat, proses atau utas akan menghentikan apa yang dilakukannya dan mengambil tindakan. Isyarat mungkin berguna untuk komunikasi antara proses.
Isyarat Piawai
Isyarat ditentukan dalam fail tajuk isyarat.h sebagai pemalar makro. Nama isyarat telah dimulakan dengan "SIG" dan diikuti dengan penerangan ringkas mengenai isyarat. Jadi, setiap isyarat mempunyai nilai angka yang unik. Program anda harus selalu menggunakan nama isyarat, bukan nombor isyarat. Sebabnya ialah nombor isyarat boleh berbeza mengikut sistem tetapi makna nama akan menjadi standard.
Makro NSIG ialah jumlah isyarat yang ditentukan. Nilai NSIG adalah lebih besar daripada jumlah isyarat yang ditentukan (Semua nombor isyarat diperuntukkan berturut-turut).
Berikut adalah isyarat standard:
Nama Isyarat | Penerangan |
PENDAPATAN | Menangguhkan proses. Isyarat SIGHUP digunakan untuk melaporkan pemutusan terminal pengguna, mungkin kerana sambungan jauh terputus atau terputus. |
TANDATANGAN | Selang proses. Apabila pengguna menaip watak INTR (biasanya Ctrl + C) isyarat SIGINT dihantar. |
TANDATANGAN | Hentikan prosesnya. Apabila pengguna menaip karakter QUIT (biasanya Ctrl + \) isyarat SIGQUIT dihantar. |
SIGILL | Arahan haram. Apabila percubaan dilakukan untuk melaksanakan sampah atau arahan istimewa, isyarat SIGILL dihasilkan. Juga, SIGILL dapat dihasilkan ketika tumpukan melimpah, atau ketika sistem mengalami masalah menjalankan pengendali isyarat. |
TANDATANGAN | Perangkap jejak. Arahan breakpoint dan arahan perangkap lain akan menghasilkan isyarat SIGTRAP. Penyahpepijat menggunakan isyarat ini. |
SIGABRT | Batalkan. Isyarat SIGABRT dihasilkan semasa fungsi batal () dipanggil. Isyarat ini menunjukkan ralat yang dikesan oleh program itu sendiri dan dilaporkan oleh panggilan fungsi batalkan (). |
SIGFPE | Pengecualian titik terapung. Apabila berlaku kesalahan aritmetik maut, isyarat SIGFPE dihasilkan. |
SIGUSR1 dan SIGUSR2 | Isyarat SIGUSR1 dan SIGUSR2 boleh digunakan mengikut kehendak anda. Adalah berguna untuk menulis pengendali isyarat untuk mereka dalam program yang menerima isyarat untuk komunikasi antara proses yang mudah. |
Tindakan Lalai Isyarat
Setiap isyarat mempunyai tindakan lalai, salah satu dari yang berikut:
Tempoh: Prosesnya akan berakhir.
Teras: Proses ini akan berakhir dan menghasilkan fail dump inti.
Ign: Prosesnya akan mengabaikan isyarat.
Berhenti: Prosesnya akan berhenti.
Sambungan: Proses akan terus dihentikan.
Tindakan lalai boleh diubah menggunakan fungsi pengendali. Sebilangan tindakan lalai isyarat tidak dapat diubah. SIGKILL dan SIGABRT tindakan lalai isyarat tidak boleh diubah atau diabaikan.
Pengendalian Isyarat
Sekiranya proses menerima isyarat, proses tersebut mempunyai pilihan tindakan untuk jenis isyarat tersebut. Prosesnya boleh mengabaikan isyarat, dapat menentukan fungsi pengendali, atau menerima tindakan lalai untuk jenis isyarat tersebut.
- Sekiranya tindakan yang ditentukan untuk isyarat diabaikan, maka isyarat akan segera dibuang.
- Program ini dapat mendaftarkan fungsi pengendali menggunakan fungsi seperti isyarat atau sigment. Ini dipanggil pengendali menangkap isyarat.
- Sekiranya isyarat tidak ditangani atau diabaikan, tindakan lalai akan berlaku.
Kami dapat menangani isyarat menggunakan isyarat atau sigment fungsi. Di sini kita melihat bagaimana yang paling mudah isyarat() fungsi digunakan untuk mengendalikan isyarat.
isyarat int () (int signum, void (* func) (int))The isyarat() akan memanggil keseronokan berfungsi sekiranya proses tersebut menerima isyarat tanda tangan. The isyarat() mengembalikan penunjuk untuk berfungsi keseronokan jika berjaya atau mengembalikan kesalahan kepada errno dan -1 sebaliknya.
The keseronokan penunjuk boleh mempunyai tiga nilai:
- SIG_DFL: Ini adalah penunjuk ke fungsi lalai sistem SIG_DFL (), diisytiharkan dalam h fail pengepala. Ia digunakan untuk mengambil tindakan lalai dari isyarat.
- SIG_IGN: Ini adalah penunjuk kepada fungsi mengabaikan sistem SIG_IGN (),diisytiharkan dalam h fail pengepala.
- Penunjuk fungsi pengendali yang ditentukan pengguna: Jenis fungsi pengendali yang ditentukan pengguna adalah tidak sah (*) (int), bermaksud jenis pengembalian adalah tidak sah dan satu argumen jenis int.
Contoh Pengendali Isyarat Asas
#sertakan#sertakan
#sertakan
batal sig_handler (int signum)
// Jenis fungsi pengendali yang dikembalikan mestilah tidak sah
printf ("\ nFungsi pengendali dalam \ n");
int utama ()
isyarat (SIGINT, sig_handler); // Daftar pengendali isyarat
untuk (int i = 1 ;; i ++) // Gelung tak terhingga
printf ("% d: Di dalam fungsi utama \ n", i);
tidur (1); // Kelewatan selama 1 saat
pulangan 0;
Dalam tangkapan skrin output Contoh1.c, kita dapat melihat bahawa dalam fungsi utama gelung tak terbatas sedang dijalankan. Semasa pengguna menaip Ctrl + C, fungsi fungsi utama berhenti dan fungsi pengendali isyarat dipanggil. Setelah selesai fungsi pengendali, pelaksanaan fungsi utama disambung semula. Apabila pengguna menggunakan Ctrl + \, prosesnya dihentikan.
Abaikan Contoh Isyarat
#sertakan#sertakan
#sertakan
int utama ()
isyarat (SIGINT, SIG_IGN); // Daftar pengendali isyarat kerana mengabaikan isyarat
untuk (int i = 1 ;; i ++) // Gelung tak terhingga
printf ("% d: Di dalam fungsi utama \ n", i);
tidur (1); // Kelewatan selama 1 saat
pulangan 0;
Di sini fungsi pengendali adalah mendaftar ke SIG_IGN () berfungsi untuk mengabaikan tindakan isyarat. Jadi, semasa pengguna menaip Ctrl + C, TANDATANGAN isyarat dihasilkan tetapi tindakannya tidak dipedulikan.
Contoh Pengendali semula Isyarat
#sertakan#sertakan
#sertakan
batal sig_handler (int signum)
printf ("\ nFungsi pengendali dalam \ n");
isyarat (SIGINT, SIG_DFL); // Daftar semula pengendali isyarat untuk tindakan lalai
int utama ()
isyarat (SIGINT, sig_handler); // Daftar pengendali isyarat
untuk (int i = 1 ;; i ++) // Gelung tak terhingga
printf ("% d: Di dalam fungsi utama \ n", i);
tidur (1); // Kelewatan selama 1 saat
pulangan 0;
Dalam tangkapan skrin output Contoh3.c, kita dapat melihat bahawa ketika pengguna pertama kali mengetik Ctrl + C, fungsi pengendali dipanggil. Dalam fungsi pengendali, pengendali isyarat mendaftar semula ke SIG_DFL untuk tindakan lalai isyarat. Apabila pengguna menaip Ctrl + C untuk kali kedua, prosesnya ditamatkan yang merupakan tindakan lalai dari TANDATANGAN isyarat.
Menghantar Isyarat:
Proses juga secara eksplisit dapat menghantar isyarat kepada dirinya sendiri atau ke proses lain. Fungsi menaikkan () dan membunuh () dapat digunakan untuk menghantar isyarat. Kedua-dua fungsi dinyatakan dalam isyarat.h tajuk fail.
kenaikan gaji int (int signum)Fungsi kenaikan () digunakan untuk menghantar isyarat tanda tangan ke proses panggilan (itu sendiri). Ia mengembalikan sifar jika berjaya dan nilai bukan sifar jika gagal.
int kill (pid_t pid, int signum)Fungsi kill digunakan untuk menghantar isyarat tanda tangan kepada proses atau kumpulan proses yang ditentukan oleh pid.
Contoh Penangan Isyarat SIGUSR1
#sertakan#sertakan
batal sig_handler (int signum)
printf ("Fungsi pengendali dalam \ n");
int utama ()
isyarat (SIGUSR1, sig_handler); // Daftar pengendali isyarat
printf ("Fungsi utama di dalam \ n");
menaikkan (SIGUSR1);
printf ("Fungsi utama di dalam \ n");
pulangan 0;
Di sini, proses menghantar isyarat SIGUSR1 ke dirinya sendiri menggunakan fungsi kenaikan ().
Naik dengan Program Contoh Bunuh
#sertakan#sertakan
#sertakan
batal sig_handler (int signum)
printf ("Fungsi pengendali dalam \ n");
int utama ()
pid_t pid;
isyarat (SIGUSR1, sig_handler); // Daftar pengendali isyarat
printf ("Fungsi utama di dalam \ n");
pid = getpid (); // Proses ID itu sendiri
bunuh (pid, SIGUSR1); // Hantarkan SIGUSR1 kepada dirinya sendiri
printf ("Fungsi utama di dalam \ n");
pulangan 0;
Di sini, proses menghantar SIGUSR1 memberi isyarat kepada dirinya menggunakan bunuh() fungsi. getpid () digunakan untuk mendapatkan ID proses itu sendiri.
Dalam contoh seterusnya kita akan melihat bagaimana proses ibu bapa dan anak berkomunikasi (Inter Process Communication) menggunakan bunuh() dan fungsi isyarat.
Komunikasi Ibu Bapa dengan Isyarat
#sertakan#sertakan
#sertakan
#sertakan
batal sig_handler_parent (int signum)
printf ("Ibu bapa: Menerima isyarat tindak balas daripada anak \ n");
batal sig_handler_child (int signum)
printf ("Anak: Menerima isyarat daripada ibu bapa \ n");
tidur (1);
bunuh (getppid (), SIGUSR1);
int utama ()
pid_t pid;
jika ((pid = garpu ())<0)
printf ("Garpu Gagal \ n");
jalan keluar (1);
/ * Proses Kanak-kanak * /
lain jika (pid == 0)
isyarat (SIGUSR1, sig_handler_child); // Daftar pengendali isyarat
printf ("Anak: menunggu isyarat \ n");
jeda ();
/ * Proses Ibu Bapa * /
lain
isyarat (SIGUSR1, sig_handler_parent); // Daftar pengendali isyarat
tidur (1);
printf ("Ibu bapa: menghantar isyarat kepada Anak \ n");
bunuh (pid, SIGUSR1);
printf ("Ibu bapa: menunggu jawapan \ n");
jeda ();
pulangan 0;
Di sini, garpu () fungsi mencipta proses anak dan mengembalikan sifar ke proses anak dan ID proses anak ke proses ibu bapa. Jadi, pid telah diperiksa untuk menentukan proses ibu bapa dan anak. Dalam proses ibu bapa, ia tidur selama 1 saat sehingga proses anak dapat mendaftarkan fungsi pengendali isyarat dan menunggu isyarat dari ibu bapa. Selepas 1 ibu bapa proses menghantar SIGUSR1 memberi isyarat kepada proses anak dan tunggu isyarat tindak balas dari anak. Dalam proses anak, pertama ia menunggu isyarat dari ibu bapa dan apabila isyarat diterima, fungsi pengendali dipanggil. Dari fungsi pengendali, proses anak menghantar yang lain SIGUSR1 isyarat kepada ibu bapa. Di sini getppid () fungsi digunakan untuk mendapatkan ID proses ibu bapa.
Kesimpulannya
Isyarat di Linux adalah topik besar. Dalam artikel ini kita telah melihat bagaimana menangani isyarat dari yang sangat asas, dan juga mendapatkan pengetahuan bagaimana isyarat menghasilkan, bagaimana proses dapat mengirim isyarat kepada dirinya sendiri dan proses lain, bagaimana isyarat dapat digunakan untuk komunikasi antara proses.