informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Sinyal (sinyal) adalah interupsi perangkat lunak. Ini adalah metode transmisi pesan antar proses. Ini digunakan untuk memberi tahu proses bahwa suatu peristiwa telah terjadi, tetapi tidak dapat meneruskan data apa pun ke proses.
Ada banyak alasan mengapa sinyal dihasilkan di Shell, yang dapat Anda gunakankill
Dankillall
Perintah untuk mengirim sinyal:
kill -信号的类型 进程编号
killall -信号的类型 进程名
nama sinyal | nilai sinyal | Tindakan pemrosesan default | Alasan untuk memberi isyarat |
---|---|---|---|
MENDESAH | 1 | A | Terminal hang atau proses kontrol berhenti |
TANDA TANGAN | 2 | A | Interupsi keyboard Ctrl+c |
SIGQUIT | 3 | C | Tombol escape pada keyboard ditekan |
SIGIL | 4 | C | Instruksi ilegal |
PERANGKAP SIG | 5 | C | instruksi titik henti |
SIGABRT | 6 | C | Sinyal batalkan yang dikeluarkan oleh batalkan(3) |
SIGBUS | 7 | C | kesalahan bus |
SIGFPE | 8 | C | pengecualian titik mengambang |
SIGKILL | 9 | A | kill -9 mematikan proses, sinyal ini tidak dapat ditangkap dan diabaikan |
SIGUSR1 | 10 | A | Sinyal yang ditentukan pengguna 1 |
SIGSEGV | 11 | C | Referensi memori tidak valid (array di luar batas, operasi penunjuk nol) |
SIGUSR2 | 12 | A | Sinyal yang ditentukan pengguna 2 |
PIPA SIG | 13 | A | Menulis data ke pipa tanpa proses membaca |
SIGALRM | 14 | A | Sinyal jam alarm, sinyal dikirim oleh fungsi alarm() |
Istilah SIG | 15 | A | Sinyal terminasi, sinyal yang dikirim secara default |
SIGSTKFLT | 16 | A | kesalahan tumpukan |
SIGCHLD | 17 | B | Dipancarkan ketika proses anak berakhir |
KONTAK SIGNAL | 18 | D | Lanjutkan proses yang dihentikan |
BERHENTI MENDAFTAR | 19 | D | Hentikan proses |
SIGTSTP | 20 | D | Terminal tekan tombol berhenti |
MENDAFTAR | 21 | D | Proses latar belakang meminta untuk membaca terminal |
SIGTTOU | 22 | D | Proses latar belakang meminta untuk menulis ke terminal |
SIGURG | 23 | B | Deteksi kondisi darurat (soket) |
SIGX CPU | 24 | C | Batas waktu CPU terlampaui |
SIGXFSZ | 25 | C | Batas ukuran file terlampaui |
SIGVTALRM | 26 | A | sinyal jam virtual |
SIGPROF | 27 | A | Analisis sinyal jam |
SIGWINCH | 28 | B | Perubahan ukuran jendela |
SIGPOLL | 29 | B | Jajak Pendapat (Sys V) |
SIGPWR | 30 | A | kegagalan listrik |
SIGSYS | 31 | C | Panggilan sistem ilegal |
Tindakan default A adalah menghentikan proses.
Tindakan default B adalah mengabaikan sinyal ini.
Tindakan default C adalah menghentikan proses dan melakukan dump image kernel.
Tindakan default D adalah menghentikan proses, dan program yang memasuki status dihentikan dapat terus dijalankan.
Ada tiga cara proses menangani sinyal:
signal()
Fungsi dapat mengatur bagaimana program menangani sinyal.
Deklarasi fungsi:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
Deskripsi Parameter:
sig
:Tentukan sinyal yang akan ditangkap.func
: Penunjuk ke fungsi pemrosesan sinyal. Fungsi pemrosesan perlu menerima parameter bilangan bulat, yaitu nomor sinyal yang ditangkap.SIG_DFL
Makro :SIG_DFL mewakili metode pemrosesan sinyal default.menggunakanSIG_DFL
sebagaisignal
Parameter kedua dari fungsi tersebut menunjukkan bahwa metode pemrosesan default sistem digunakan untuk sinyal.SIG_IGN
Makro :SIG_IGN berarti mengabaikan sinyal.menggunakanSIG_IGN
sebagaisignal
Parameter kedua dari fungsi tersebut menunjukkan bahwa ketika proses menerima sinyal, proses tersebut akan mengabaikannya dan tidak melakukan pemrosesan apa pun. Hal ini dapat mencegah proses dihentikan atau diinterupsi secara tidak terduga dalam keadaan tertentu.SIG_ERR
:SIG_ERR
Makro digunakan untuk menunjukkan kesalahan.itu tidak sepertisignal
Parameter kedua dari fungsi tersebut digunakan sebagaisignal
Nilai kembalian fungsi menunjukkan bahwa panggilan gagal.jikasignal
Jika panggilan ke fungsi gagal, fungsi tersebut akan kembaliSIG_ERR
.Ini biasanya digunakan untuk mendeteksi dan memprosessignal
Kesalahan dalam pemanggilan fungsi.Program layanan berjalan di latar belakang. Jika Anda ingin menghentikannya, mematikannya bukanlah ide yang baik, karena ketika proses dihentikan, ia mati secara tiba-tiba dan tidak ada pekerjaan setelahnya yang diatur.
Jika Anda mengirim sinyal ke program layanan, setelah menerima sinyal, program layanan memanggil suatu fungsi dan menulis kode akibatnya dalam fungsi tersebut, dan program dapat keluar secara terencana.
Mengirimkan sinyal 0 ke program layanan dapat mendeteksi apakah program tersebut hidup.
Sistem operasi Linux menyediakan kill
Dankillall
Perintah tersebut mengirimkan sinyal ke programkill()
Fungsi perpustakaan mengirimkan sinyal ke proses lain.
Deklarasi fungsi:
int kill(pid_t pid, int sig);
kill()
Fungsi ini mengambil parametersig
Sinyal yang ditentukan diteruskan ke parameterpid
proses yang ditentukan.
parameter pid
Ada beberapa situasi:
pid > 0
Lewati sinyal ke proses sebagaipid
proses.pid = 0
Meneruskan sinyal ke semua proses dalam grup proses yang sama dengan proses saat ini. Hal ini sering digunakan oleh proses induk untuk mengirim sinyal ke proses anak.pid < -1
Lewati sinyal ke ID grup proses|pid|
dari semua proses.pid = -1
Meneruskan sinyal ke semua proses yang memiliki izin untuk mengirimkan sinyal, tetapi tidak ke proses yang mengirimkan sinyal.Ada 8 cara untuk menghentikan suatu proses, 5 diantaranya merupakan penghentian normal, yaitu:
main()
Untuk fungsireturn
kembali;exit()
fungsi;_exit()
atau_Exit()
fungsi;return
kembali;pthread_exit()
kembali;Ada tiga cara untuk mengakhiri secara tidak normal, yaitu:
abort()
fungsi dibatalkan;ada main()
Dalam fungsinya,return
Nilai yang dikembalikan adalah status penghentian, jika tidakreturn
pernyataan atau panggilanexit()
, maka status penghentian proses adalah 0.
Di shell, lihat status penghentian proses:
echo $?
3 fungsi untuk menghentikan proses secara normal (exit()
Dan_Exit()
ditentukan oleh ISO C,_exit()
ditentukan oleh POSIX):
void exit(int status);
void _exit(int status);
void _Exit(int status);
status
Status penghentian proses.
return
Menunjukkan bahwa ketika fungsi kembali, destruktor objek lokal akan dipanggil.main()
dalam fungsireturn
Penghancur objek global juga disebut.exit()
Menunjukkan untuk menghentikan proses, destruktor objek lokal tidak akan dipanggil, hanya destruktor objek global yang akan dipanggil._exit()
Dan_Exit()
Keluar secara langsung dan tidak ada pekerjaan pembersihan yang akan dilakukan.Prosesnya tersedia atexit()
Registrasi fungsi mengakhiri fungsi (hingga 32), fungsi-fungsi ini akanexit()
Dipanggil secara otomatis.
int atexit(void (*function)(void));
exit()
Urutan pemanggilan fungsi terminasi dibalik sejak saat registrasi.
system()
Fungsi ini menyediakan metode sederhana untuk mengeksekusi program, meneruskan program dan parameter yang perlu dieksekusi sebagai string.system()
Hanya berfungsi.
Deklarasi fungsi:
int system(const char * string);
system()
Nilai kembalian dari fungsi tersebut lebih merepotkan.
system()
Fungsi ini mengembalikan bukan nol;system()
Fungsi ini mengembalikan 0;system()
Fungsi ini mengembalikan bukan nol.exec
Keluarga fungsi menyediakan cara lain untuk memanggil program (biner atau skrip shell) dalam suatu proses.
exec
Keluarga fungsi dideklarasikan sebagai berikut:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
Melihat:
errno
tengah.exec
Setelah itu program yang dipanggil akan menggantikan program pemanggil, yaituexec
Tidak ada kode setelah fungsi akan dijalankan.execl()
Danexecv()
, yang lain jarang digunakan.Semua proses di seluruh sistem Linux berada dalam struktur pohon.
menggunakanpstree
Anda dapat melihat pohon proses dengan perintah:
pstree -p 进程编号
Setiap proses memiliki ID proses unik yang diwakili oleh bilangan bulat non-negatif. Meskipun unik, ID proses dapat digunakan kembali. Ketika suatu proses dihentikan, ID prosesnya menjadi kandidat untuk digunakan kembali. Linux menggunakan algoritma penggunaan kembali yang tertunda sehingga ID dari proses yang baru dibuat berbeda dengan ID yang digunakan oleh proses yang baru saja dihentikan. Hal ini mencegah proses baru disalahartikan sebagai proses yang dihentikan menggunakan ID yang sama.
Fungsi untuk mendapatkan ID proses:
pid_t getpid(void); // 获取当前进程的ID。
pid_t getppid(void); // 获取父进程的ID。
Proses yang ada dapat memanggilfork()
Fungsi menciptakan proses baru.
Deklarasi fungsi:
pid_t fork(void);
Bergantung padafork()
Proses baru yang dibuat disebut proses anak.
fork()
Fungsi ini dipanggil sekali tetapi kembali dua kali. Perbedaan antara kedua return tersebut adalah nilai return dari proses anak adalah 0, sedangkan nilai return dari proses induk adalah ID proses dari proses anak yang baru dibuat.
Proses anak dan proses induk terus dijalankanfork()
Kode setelah itu, Proses anak adalah salinan dari proses induk. Proses anak memiliki salinan ruang data, heap, dan tumpukan proses induk (catatan: proses anak memiliki salinan, tidak dibagikan dengan proses induk).
fork()
Setelah itu, urutan eksekusi proses induk dan anak tidak ditentukan.
fork()
, biarkan proses anak menangani permintaan ini, sementara proses induk terus menunggu permintaan koneksi berikutnya.fork()
Dipanggil segera setelah kembaliexec
。fork()
Salah satu fiturnya adalah deskriptor file yang dibuka dalam proses induk akan disalin ke proses anak, dan proses induk serta proses anak berbagi offset file yang sama.
Jika proses induk dan proses anak menulis ke file yang ditunjuk oleh deskriptor yang sama tanpa sinkronisasi apa pun, outputnya mungkin tercampur satu sama lain.
Pada titik ini Anda dapat melihat bahwa hanya ada 100.000 baris data.
Saat ini, seharusnya ada 200.000 baris data. Kurangnya satu baris mungkin karena operasi penulisan file tidak bersifat atomik, jika tidak ada mekanisme sinkronisasi, dua proses mungkin mencoba menulis bagian file yang berbeda secara bersamaan. menyebabkan penulisan gagal.
vfork()
Pemanggilan fungsi dan nilai kembalian sama denganfork()
Sama, namun semantiknya berbeda.
vfork()
Fungsi tersebut digunakan untuk membuat proses baru yang tujuannya adalahexec
Sebuah program baru yang tidak menyalin ruang alamat proses induk karena proses anak langsung memanggilexec
, sehingga ruang alamat proses induk tidak akan digunakan. Jika proses anak menggunakan ruang alamat dari proses induk, hasil yang tidak diketahui mungkin terjadi.
vfork()
Danfork()
Perbedaan lainnya adalah:vfork()
Pastikan proses anak berjalan terlebih dahulu dan panggil proses tersebut dalam proses anakexec
atauexit
Kemudian proses induk melanjutkan operasi.
Dalam sistem operasi, proses zombie mengacu pada proses anak yang telah dihentikan namun proses induknya belum membaca status keluarnya. Meskipun proses zombie tidak lagi berjalan, proses ini masih menempati entri dalam tabel proses sehingga kernel dapat menyimpan informasi status keluar proses (seperti ID proses, status keluar, dll.) hingga proses induk membaca informasi ini.
Jika proses induk keluar sebelum proses anak, proses anak akan di-host oleh proses 1 (ini juga merupakan cara untuk membiarkan proses berjalan di latar belakang).
Jika proses anak keluar sebelum proses induk, dan proses induk tidak memproses informasi keluar dari proses anak, maka proses anak akan menjadi proses zombie.
Kernel menyimpan struktur data untuk setiap proses anak, termasuk nomor proses, status terminasi, waktu CPU yang digunakan, dll. Jika proses induk memproses informasi keluar dari proses anak, kernel akan melepaskan struktur data ini. Jika proses induk tidak memproses informasi keluar dari proses anak, kernel tidak akan melepaskan struktur data ini, dan nomor proses dari proses anak akan selalu terisi. Jumlah proses yang tersedia dalam sistem terbatas. Jika proses zombie dihasilkan dalam jumlah besar, sistem tidak akan dapat menghasilkan proses baru karena tidak ada nomor proses yang tersedia.
signal(SIGCHLD, SIG_IGN)
Beri tahu kernel bahwa ia tidak tertarik dengan keluarnya proses anak, dan struktur datanya akan segera dirilis setelah proses anak keluar.wait()
/waitpid()
fungsi: Proses induk menunggu hingga proses anak selesai dengan memanggil fungsi-fungsi ini dan memperoleh status keluarnya, sehingga melepaskan sumber daya yang ditempati oleh proses anak.pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid, int *stat_loc, int options);
pid_t wait3(int *status, int options, struct rusage *rusage);
pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
Nilai yang dikembalikan adalah jumlah proses anak.
stat_loc
Apakah informasi tentang penghentian proses anak:
a) Jika diakhiri secara normal, makro WIFEXITED(stat_loc)
Kembalikan benar, makroWEXITSTATUS(stat_loc)
Status penghentian dapat diperoleh;
b) Jika berakhir secara tidak normal, makro WTERMSIG(stat_loc)
Mendapat sinyal untuk menghentikan proses.
Jika proses induk sedang sibuk, Anda dapat menangkapnya SIGCHLD
Sinyal, disebut dalam fungsi pemrosesan sinyalwait()
/waitpid()
。
[Kirim sinyal antar proses](##1.5 Kirim sinyal)
Dalam program layanan multiproses, jika subproses menerima sinyal keluar, subproses akan keluar dengan sendirinya.
Jika proses induk menerima sinyal keluar, maka proses tersebut harus mengirimkan sinyal keluar ke semua proses anak dan kemudian keluar sendiri.
Multi-thread berbagi ruang alamat suatu proses,Jika beberapa thread perlu mengakses memori yang sama, gunakan saja variabel global.。
Dalam beberapa proses, ruang alamat setiap proses bersifat independen dan tidak dibagikan.Jika beberapa proses perlu mengakses memori yang sama, variabel global tidak dapat digunakan, hanya memori bersama yang dapat digunakan.。
Memori Bersama memungkinkan banyak proses (tidak diperlukan hubungan darah antar proses) untuk mengakses ruang memori yang sama. Ini adalah cara paling efektif untuk berbagi dan mentransfer data antar beberapa proses. Proses dapat menghubungkan memori bersama ke ruang alamatnya sendiri. Jika satu proses memodifikasi data di memori bersama, data yang dibaca oleh proses lain juga akan berubah.
Memori bersama tidak menyediakan mekanisme kunci, artinya, ketika suatu proses membaca/menulis memori bersama, hal ini tidak menghalangi proses lain untuk membaca/menulisnya.Jika Anda ingin mengunci baca/tulis memori bersama, Anda dapat menggunakan semaphore . Linux menyediakan serangkaian fungsi untuk mengoperasikan memori bersama.
Fungsi ini digunakan untuk membuat/memperoleh memori bersama.
int shmget(key_t key, size_t size, int shmflg);
typedef unsigned int key_t
), umumnya dalam heksadesimal, misalnya 0x5005
, kunci dari kenangan bersama yang berbeda tidak boleh sama.0666|IPC_CREAT
Menunjukkan bahwa jika memori bersama tidak ada, buatlah.menggunakan ipcs -m
Anda dapat melihat memori bersama sistem, termasuk: kunci, id memori bersama (shmid), pemilik, izin (perm), dan ukuran (byte).
menggunakan ipcrm -m 共享内存id
Memori bersama dapat dihapus secara manual sebagai berikut:
Catatan: Kontainer tidak dapat digunakan untuk tipe data di memori bersama, hanya tipe data dasar yang dapat digunakan.
Fungsi ini digunakan untuk menghubungkan memori bersama ke ruang alamat proses saat ini.
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmget()
Pengidentifikasi memori bersama dikembalikan oleh fungsi.Mengembalikan alamat awal memori bersama ketika panggilan berhasil, dan kembali ketika gagal. (void *)-1
。
Fungsi ini digunakan untuk melepaskan memori bersama dari proses saat ini, yang setara dengan shmat()
Operasi kebalikan dari suatu fungsi.
int shmdt(const void *shmaddr);
shmat()
Alamat yang dikembalikan oleh fungsi.Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.
Fungsi ini digunakan untuk mengoperasikan memori bersama. Operasi yang paling umum digunakan adalah menghapus memori bersama.
int shmctl(int shmid, int command, struct shmid_ds *buf);
shmget()
Id memori bersama dikembalikan oleh fungsi.IPC_RMID
。Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.
Catatan, gunakan root
Memori bersama yang dibuat tidak dapat dihapus oleh pengguna biasa terlepas dari izin yang dibuat.
Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.
Fungsi ini digunakan untuk mengoperasikan memori bersama. Operasi yang paling umum digunakan adalah menghapus memori bersama.
int shmctl(int shmid, int command, struct shmid_ds *buf);
shmget()
Id memori bersama dikembalikan oleh fungsi.IPC_RMID
。Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.
Catatan, gunakan root
Memori bersama yang dibuat tidak dapat dihapus oleh pengguna biasa terlepas dari izin yang dibuat.
[Gambar tautan eksternal sedang ditransfer...(img-v6qW3XRA-1720711279572)]
[Gambar tautan eksternal sedang ditransfer...(img-CG0tGAne-1720711279572)]