Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk membangunkan proses daemon dalam bahasa Go?

Bagaimana untuk membangunkan proses daemon dalam bahasa Go?

王林
王林asal
2023-06-11 09:55:531653semak imbas

Bahasa Go ialah bahasa pengaturcaraan yang pantas dan cekap Ia mempunyai ciri yang baik dalam pembangunan proses daemon, seperti sokongan serentak terbina dalam, benang ringan, mekanisme pengumpulan sampah, dsb. Daemon ialah program yang boleh dilaksanakan di latar belakang Ia biasanya perlu dijalankan untuk masa yang lama, sentiasa mendengar acara luaran, seperti permintaan sambungan rangkaian, dan memproses peristiwa yang berlaku dengan sewajarnya. Artikel ini akan memperkenalkan cara membangunkan proses daemon dalam bahasa Go.

1. Keperluan asas proses daemon

Dalam sistem pengendalian Linux dan Unix, proses daemon perlu memenuhi beberapa keperluan asas:

  1. Mesti mempunyai proses induk , Proses induk ini adalah sebaik-baiknya proses init, yang memastikan bahawa daemon masih boleh berjalan selepas sistem dimulakan semula.
  2. Daemon perlu meletakkan dirinya ke latar belakang apabila ia bermula dan melepaskan terminal kawalan.
  3. Daemon perlu boleh mengendalikan isyarat seperti SIGTERM dan SIGINT untuk membersihkan dirinya dengan betul apabila sistem dimatikan atau ditamatkan.

2 Langkah untuk melaksanakan proses daemon

Membangunkan proses daemon dalam bahasa Go memerlukan melengkapkan langkah berikut:

  1. Buat proses anak dan keluar Proses induk;
  2. Panggil fungsi setsid() untuk mencipta kumpulan sesi baharu dan menjadikan proses semasa sebagai ketua kumpulan sesi dan satu-satunya ahli kumpulan proses baharu; Tutup deskriptor fail 0, 1, 2 (input standard, output standard, output ralat standard); ia sebagai Direktori kerja dan sistem fail akar proses; membersihkan sumber program dengan betul.
  3. Di bawah, kami akan memperkenalkan pelaksanaan khusus langkah-langkah ini satu demi satu.
  4. 3. Butiran pelaksanaan
  5. Buat proses anak dan keluar dari proses induk

Coretan kod untuk mencipta proses anak dan keluar dari proses induk dalam bahasa Go adalah seperti berikut :

func startDaemon() {
    cmd := exec.Command(os.Args[0])
    cmd.Start()
    os.Exit(0)
}

Kod ini akan memulakan proses baharu dan keluar daripada proses semasa, menjadikan proses baharu sebagai proses anak daemon.

  1. Buat kumpulan perbualan baharu

Coretan kod untuk mencipta kumpulan perbualan baharu dalam bahasa Go adalah seperti berikut:

func startDaemon() {
    syscall.Umask(0)
    if syscall.Getppid() == 1 {
        return
    }
    cmd := exec.Command(os.Args[0])
    cmd.Start()
    os.Exit(0)
    ...
    sysret, syserr := syscall.Setsid()
    if syserr != nil || sysret < 0 {
        fmt.Fprintf(os.Stderr, "Error: syscall.Setsid errno:%d %v
", syserr, syserr)
        os.Exit(1)
    }
}

Kod ini mula-mula ditetapkan up the file Topeng kebenaran ialah 0, dan kemudian semak sama ada proses semasa sudah menjadi proses peneraju kumpulan sesi (iaitu, sama ada proses induk ialah proses init). Jika ya, tidak perlu membuat kumpulan perbualan baharu. Jika tidak, panggil fungsi setsid() yang dinyatakan di atas untuk mencipta kumpulan sesi baharu dan menjadikan proses semasa sebagai ketua kumpulan sesi.

  1. Tutup deskriptor fail

Dalam bahasa Go, serpihan kod untuk menutup deskriptor fail adalah seperti berikut:

func startDaemon() {
    syscall.Umask(0)
    if syscall.Getppid() == 1 {
        return
    }
    cmd := exec.Command(os.Args[0])
    cmd.Start()
    os.Exit(0)
    ...
    syscall.Close(0)    // close stdin
    syscall.Close(1)    // close stdout
    syscall.Close(2)    // close stderr
}

Kod ini menggunakan syscall pakej Fungsi Close() menutup deskriptor fail 0, 1, dan 2.

  1. Buat direktori boleh tulis

Coretan kod untuk mencipta direktori boleh tulis dalam bahasa Go adalah seperti berikut:

func startDaemon() {
    syscall.Umask(0)
    if syscall.Getppid() == 1 {
        return
    }
    cmd := exec.Command(os.Args[0])
    cmd.Start()
    os.Exit(0)
    ...
    os.Chdir("/")
    dir, _ := ioutil.TempDir("", "")
    fd, _ := os.Open(dir)
    syscall.Dup2(int(fd.Fd()), 0)
    syscall.Dup2(int(fd.Fd()), 1)
    syscall.Dup2(int(fd.Fd()), 2)
}

Kod ini mula-mula mengalih keluar proses Tukar direktori kerja semasa kepada direktori akar (/), dan kemudian gunakan fungsi TempDir() dalam pakej ioutil untuk mencipta direktori baharu di bawah direktori /tmp. Seterusnya, gunakan fungsi os.Open() untuk membuka direktori dan gunakan fungsi Dup2() dalam pakej syscall untuk menyalin deskriptor failnya ke deskriptor fail untuk input standard, output standard dan ralat standard.

  1. Muat sumber yang diperlukan

Coretan kod untuk memuatkan sumber yang diperlukan boleh ditulis dalam fungsi kemasukan program.

Memproses isyarat SIGTERM dan SIGINT
  1. Kod untuk memproses isyarat SIGTERM dan SIGINT dalam bahasa Go adalah seperti berikut:
func main() {
    ...
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-c
        // 执行清理操作
        os.Exit(0)
    }()
    ...
}

Kod ini menggunakan os pakej Fungsi Signal() memindahkan isyarat SIGTERM dan SIGINT ke saluran paip untuk diproses. Kemudian, dengan mendengar paip ini dalam goroutine lain, anda boleh melakukan operasi pembersihan apabila isyarat ini diterima.

    4. Ringkasan
  1. Artikel ini memperkenalkan cara membangunkan proses daemon dalam bahasa Go. Daemon ialah program jangka panjang yang perlu mengendalikan pelbagai acara luaran Ia perlu memenuhi beberapa keperluan asas, seperti mempunyai proses induk, meletakkan dirinya di latar belakang apabila bermula, dsb. Kaedah untuk melaksanakan keperluan ini dalam bahasa Go termasuk mencipta proses anak dan keluar daripada proses induk, mencipta kumpulan sesi baharu, menutup deskriptor fail, mencipta direktori boleh tulis, memuatkan sumber yang diperlukan dan mengendalikan isyarat SIGTERM dan SIGINT, dsb. Menguasai kaedah ini, kita boleh membangunkan proses daemon secara bebas dalam bahasa Go.

Atas ialah kandungan terperinci Bagaimana untuk membangunkan proses daemon dalam bahasa Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn