ホームページ >バックエンド開発 >Golang >Golang がどのようにデーモン プロセスを作成し、スムーズに再起動するかを分析する

Golang がどのようにデーモン プロセスを作成し、スムーズに再起動するかを分析する

藏色散人
藏色散人転載
2021-07-23 14:25:472661ブラウズ

PHP 開発のベテランとして。コマンドラインを使用して、nginx や PHP-FPM などの操作を開始/再起動/停止します。非常に感動。もしC/Cを使ってこのようなシステムを開発してくださいと言われたら、私には絶対にそんな気力はありません。しかし、Golang が私の視界に入って以来。すべてとても簡単だと思いました。

1) デーモン プロセスを生成する

コードに直接移動します:

package main

import (
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    //判 断当其是否是子进程,当父进程return之后,子进程会被 系统1 号进程接管
    if os.Getppid() != 1 {
        // 将命令行参数中执行文件路径转换成可用路径
        filePath, _ := filepath.Abs(os.Args[0])
        cmd := exec.Command(filePath, os.Args[1:]...)
        // 将其他命令传入生成出的进程
        cmd.Stdin = os.Stdin // 给新进程设置文件描述符,可以重定向到文件中
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.Start() // 开始执行新进程,不等待新进程退出
        return
    }
}

Linux システムに詳しい人は知っておくべきです: ユーザーが作成したデーモン プロセスは、次のユーザーによって使用されます。 LinuxシステムのプロセスNo.1が引き継ぎます。つまり、上記のコードは Linux システムでのみ実行できます。私は Unix システムで遊んだことがありません。したがって、具体的な提案はできません。

インターネットで、デーモン プロセスを作成する他の方法があることを知りました。ただし、私にとって良いと思われるのは上記のソースコード方法だけです。プロジェクトでうまく使用されています。

例:

os.StartProcess() 创建守护进程。
syscall.RawSyscall() 创建守护进程。

exec.Command のみがデーモン プロセスを作成する最も高度な方法です。最高のカプセル化。このテストを使用することをお勧めします。

2) デーモン プロセスの開始/再起動/停止

ポイント 1 では、デーモン プロセスが正常に開始されました。ただし、kill コマンドを使用して終了することはできません。その後、再度開始してください。したがって、業界の専門的なアプローチであるシグナルを使用する必要があります。

実行中のプロセスは、送信されたシグナルを受信できます。 Linux に関するシグナルは数多くあります。 Google でキーワード「Linux シグナル」を検索できます。

ソース コードに直接アクセスします:

package main

import "fmt"
import "os"
import "os/signal"
import "syscall"

func main() {

    // Go signal notification works by sending `os.Signal`
    // values on a channel. We'll create a channel to
    // receive these notifications (we'll also make one to
    // notify us when the program can exit).
    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)

    // `signal.Notify` registers the given channel to
    // receive notifications of the specified signals.
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    // This goroutine executes a blocking receive for
    // signals. When it gets one it'll print it out
    // and then notify the program that it can finish.
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
    }()

    // The program will wait here until it gets the
    // expected signal (as indicated by the goroutine
    // above sending a value on `done`) and then exit.
    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}

重要なポイントは 3 つあります:
1) 信号の登録
2) 信号の受信
3) 信号の処理。

デーモンプロセスの作成とセマフォ処理を統合すれば、デーモンプロセスを管理するコマンドを実装できます。

golang 関連の技術記事をさらに詳しく知りたい場合は、golang チュートリアル列をご覧ください。

以上がGolang がどのようにデーモン プロセスを作成し、スムーズに再起動するかを分析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjianshu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。