Saya ingin menangkap sinyal Ctrl+C( SIGINT
) yang dikirim dari konsol dan mencetak beberapa total run parsial.
Apakah ini mungkin di Golang?
Catatan: Ketika saya pertama kali memposting pertanyaan saya bingung tentang Ctrl+Cmenjadi SIGTERM
bukan SIGINT
.
for sig := range g {
, Anda juga dapat menggunakan<-sigchan
seperti pada jawaban sebelumnya: stackoverflow.com/questions/8403862/…go run
di konsol dan mengirim SIGTERM melalui ^ C, sinyal ditulis ke dalam saluran dan program merespons, tetapi tampaknya keluar dari loop secara tak terduga. Ini karena SIGRERM juga berlakugo run
! (Ini membuat saya banyak kebingungan!)runtime.Gosched
di tempat yang sesuai (di loop utama program Anda, jika ada)Ini bekerja:
sumber
Untuk menambahkan sedikit ke jawaban lain, jika Anda benar-benar ingin menangkap SIGTERM (sinyal default yang dikirim oleh perintah kill), Anda dapat menggunakannya
syscall.SIGTERM
sebagai ganti os.Interrupt. Berhati-hatilah karena antarmuka syscall khusus untuk sistem dan mungkin tidak berfungsi di mana-mana (mis. Di windows). Tetapi bekerja dengan baik untuk menangkap keduanya:sumber
signal.Notify
Fungsi memungkinkan untuk menentukan beberapa sinyal sekaligus. Dengan demikian, Anda dapat menyederhanakan kode Anda menjadisignal.Notify(c, os.Interrupt, syscall.SIGTERM)
.os.Kill
sesuai dengansyscall.Kill
, yang merupakan sinyal yang dapat dikirim tetapi tidak ditangkap. Ini setara dengan perintahkill -9 <pid>
. Jika Anda ingin menangkapkill <pid>
dan mematikan dengan anggun, Anda harus menggunakannyasyscall.SIGTERM
.Ada (pada saat posting) satu atau dua kesalahan ketik kecil dalam jawaban yang diterima di atas, jadi inilah versi yang dibersihkan. Dalam contoh ini saya menghentikan profiler CPU ketika menerima Ctrl+ C.
sumber
runtime.Gosched
di tempat yang sesuai (di loop utama program Anda, jika ada)Semua hal di atas tampaknya berfungsi ketika disambung, tetapi halaman sinyal gobyexample memiliki contoh penangkapan sinyal yang benar-benar bersih dan lengkap. Layak ditambahkan ke daftar ini.
sumber
Kematian adalah perpustakaan sederhana yang menggunakan saluran dan grup tunggu untuk menunggu sinyal penutupan. Setelah sinyal diterima, maka akan memanggil metode penutupan pada semua struct Anda yang ingin Anda bersihkan.
sumber
Anda dapat memiliki goroutine berbeda yang mendeteksi sinyal syscall.SIGINT dan syscall.SIGTERM dan menyampaikannya ke saluran menggunakan sinyal.Notify . Anda dapat mengirim kail ke goroutine itu menggunakan saluran dan menyimpannya dalam irisan fungsi. Ketika sinyal shutdown terdeteksi pada saluran, Anda dapat menjalankan fungsi-fungsi tersebut di slice. Ini dapat digunakan untuk membersihkan sumber daya, menunggu goroutine berjalan untuk menyelesaikan, bertahan data, atau mencetak total menjalankan parsial.
Saya menulis sebuah utilitas kecil dan sederhana untuk menambah dan menjalankan hook saat shutdown. Semoga bisa membantu.
https://github.com/ankit-arora/go-utils/blob/master/go-shutdown-hook/shutdown-hook.go
Anda dapat melakukan ini dengan cara 'menunda'.
contoh untuk mematikan server dengan anggun:
sumber
Ini adalah versi lain yang berfungsi jika Anda memiliki beberapa tugas untuk dibersihkan. Kode akan meninggalkan proses pembersihan dalam metode mereka.
jika Anda perlu membersihkan fungsi utama, Anda perlu menangkap sinyal di utas utama menggunakan go func () juga.
sumber
Sekadar catatan jika seseorang membutuhkan cara untuk menangani sinyal di Windows. Saya memiliki persyaratan untuk menangani dari prog A memanggil prog B melalui os / exec tetapi prog B tidak pernah dapat mengakhiri dengan anggun karena mengirim sinyal melalui ex. cmd.Process.Signal (syscall.SIGTERM) atau sinyal lain tidak didukung pada Windows. Cara saya menangani adalah dengan membuat file temp sebagai ex sinyal. .signal.term melalui prog A dan prog B perlu memeriksa apakah file itu ada pada interval dasar, jika ada file itu akan keluar dari program dan menangani pembersihan jika diperlukan, saya yakin ada cara lain tetapi ini berhasil.
sumber