Maison >développement back-end >Golang >Comment développer un processus démon en langage Go ?

Comment développer un processus démon en langage Go ?

王林
王林original
2023-06-11 09:55:531669parcourir

Le langage Go est un langage de programmation rapide et efficace. Il possède de bonnes fonctionnalités dans le développement de processus démons, telles que la prise en charge intégrée de la concurrence, des threads légers, un mécanisme de récupération de place, etc. Un démon est un programme qui peut être exécuté en arrière-plan. Il doit généralement s'exécuter pendant une longue période, en écoutant constamment les événements externes, tels que les demandes de connexion réseau, et en traitant les événements qui se produisent en conséquence. Cet article explique comment développer un processus démon en langage Go.

1. Exigences de base du processus démon

Dans les systèmes d'exploitation Linux et Unix, un processus démon doit répondre à certaines exigences de base :

  1. Ce processus parent est de préférence un processus d'initialisation, qui peut garantir. que le système redémarre. Le démon back peut toujours s'exécuter.
  2. Le démon doit se mettre en arrière-plan lorsqu'il démarre et libérer le terminal de contrôle.
  3. Le démon doit être capable de gérer des signaux tels que SIGTERM et SIGINT afin de se nettoyer correctement lorsque le système s'arrête ou se termine.

2. Étapes pour implémenter un processus démon

Développer un processus démon en langage Go nécessite de suivre les étapes suivantes :

  1. Créez un processus enfant et quittez le processus parent
  2. Appelez la fonction setsid() pour créer un nouveau processus ; groupe de session, et Faire du processus actuel le leader du groupe de session et le seul membre du nouveau groupe de processus ;
  3. Fermer les descripteurs de fichiers 0, 1, 2 (entrée standard, sortie standard, sortie d'erreur standard) ; répertoire racine du système de fichiers (/), ouvrez son descripteur de fichier, puis utilisez-le comme répertoire de travail et système de fichiers racine du processus ;
  4. Chargez les ressources nécessaires au démarrage du programme, y compris les fichiers de configuration, les variables d'environnement, etc. . ;
  5. Gérez les signaux SIGTERM et SIGINT pour nettoyer correctement les ressources du programme.
  6. Ci-dessous, nous présenterons une à une la mise en œuvre spécifique de ces étapes.

3. Détails d'implémentation

Créer un processus enfant et quitter le processus parent
  1. L'extrait de code pour créer un processus enfant et quitter le processus parent en langage Go est le suivant :
func startDaemon() {
    cmd := exec.Command(os.Args[0])
    cmd.Start()
    os.Exit(0)
}

Ce code démarrera un nouveau processus et quittez le processus actuel, faisant du nouveau processus un processus enfant du démon.

Créer un nouveau groupe de conversation
  1. Le fragment de code pour créer un nouveau groupe de conversation en langage Go est le suivant :
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)
    }
}

Ce code définit d'abord le masque d'autorisation de fichier sur 0, puis vérifie si le processus en cours est déjà un groupe de conversation Le processus principal (c'est-à-dire si le processus parent est le processus d'initialisation). Si tel est le cas, il n'est pas nécessaire de créer un nouveau groupe de conversation. Sinon, appelez la fonction setsid() mentionnée ci-dessus pour créer un nouveau groupe de session et faire du processus actuel le leader du groupe de session.

Fermez le descripteur de fichier
  1. Dans le langage Go, l'extrait de code pour fermer le descripteur de fichier est le suivant :
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
}

Ce code utilise la fonction Close() du package syscall pour fermer les descripteurs de fichier 0, 1, et 2.

Créer un répertoire inscriptible
  1. L'extrait de code pour créer un répertoire inscriptible en langage Go est le suivant :
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)
}

Ce code change d'abord le répertoire de travail actuel du processus en répertoire racine (/), puis utilise le package ioutil La fonction TempDir() crée un nouveau répertoire sous le répertoire /tmp. Ensuite, utilisez la fonction os.Open() pour ouvrir le répertoire et utilisez la fonction Dup2() dans le package syscall pour copier ses descripteurs de fichier dans les descripteurs de fichier pour l'entrée standard, la sortie standard et l'erreur standard.

Charger les ressources requises
  1. L'extrait de code pour charger les ressources requises peut être écrit dans la fonction de saisie du programme.

Traitement des signaux SIGTERM et SIGINT
  1. Le code de traitement des signaux SIGTERM et SIGINT en langage Go est le suivant :
func main() {
    ...
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-c
        // 执行清理操作
        os.Exit(0)
    }()
    ...
}

Ce code utilise la fonction Signal() du package os pour transférer les signaux SIGTERM et SIGINT vers un pipeline respectivement pour le traitement. Ensuite, en écoutant ce tube dans une autre goroutine, vous pouvez effectuer des opérations de nettoyage lorsque ces signaux sont reçus.

4. Résumé

Cet article présente comment développer des processus démons en langage Go. Un démon est un programme de longue durée qui doit gérer divers événements externes. Il doit répondre à certaines exigences de base, comme avoir un processus parent, se mettre en arrière-plan lors du démarrage, etc. Les méthodes pour implémenter ces exigences dans le langage Go incluent la création d'un processus enfant et la sortie du processus parent, la création d'un nouveau groupe de sessions, la fermeture des descripteurs de fichiers, la création d'un répertoire inscriptible, le chargement des ressources requises et la gestion des signaux SIGTERM et SIGINT. En maîtrisant ces méthodes, nous pouvons développer librement des processus démons dans le langage Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn