精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

探索Go守護進程的實現方法

開發 前端
在Go中實現守護進程化,雖然因為語言運行時的特性而具有挑戰性,但通過社區開發的庫和謹慎的實現是可以實現的。

在后端開發的世界里,守護進程(daemon)這個概念與Unix系統一樣古老。守護進程是在后臺運行的長期服務程序,不與任何終端關聯。盡管現代進程管理工具如systemd[1]和supervisor[2]等讓應用轉化為守護進程變得十分簡單,我們甚至可以使用以下命令來在后臺運行程序:

nohup ./your_go_program &

但在某些情況下,程序的原生轉化為守護進程的能力仍然是有必要的。比如分布式文件系統juicefs cli的mount子命令,它就支持以-d選項啟動,并以守護進程方式運行:

$juicefs mount -h
NAME:
   juicefs mount - Mount a volume

USAGE:
   juicefs mount [command options] META-URL MOUNTPOINT

... ...

OPTIONS:
   -d, --background  run in background (default: false)
   ... ...
... ...

這種自我守護化的能力會讓很多Go程序受益,在這一篇文章中,我們就來探索一下Go應用轉化為守護進程的實現方法。

1. 標準的守護進程轉化方法

[W.Richard Stevens]( "W.Richard Stevens")的經典著作《UNIX環境高級編程[3]》中對將程序轉化為一個守護進程的 (daemonize) 步驟進行了詳細的說明,主要步驟如下:

  • 創建子進程并終止父進程

通過fork()系統調用創建子進程,父進程立即終止,保證子進程不是控制終端的會話組首領。

  • 創建新的會話

子進程調用setsid()來創建一個新會話,成為會話組首領,從而擺脫控制終端和進程組。

  • 更改工作目錄

使用chdir("/") 將當前工作目錄更改為根目錄,避免守護進程持有任何工作目錄的引用,防止對文件系統卸載的阻止。

  • 重設文件權限掩碼

通過umask(0) 清除文件權限掩碼,使得守護進程可以自由設置文件權限。

  • 關閉文件描述符

關閉繼承自父進程的已經open的文件描述符(通常是標準輸入、標準輸出和標準錯誤)。

  • 重定向標準輸入/輸出/錯誤

重新打開標準輸入、輸出和錯誤,重定向到/dev/null,以避免守護進程無意輸出內容到不應有的地方。

注:fork()系統調用是一個較為難理解的調用,它用于在UNIX/Linux系統中創建一個新的進程。新創建的進程被稱為子進程,它是由調用fork()的進程(即父進程)復制出來的。子進程與父進程擁有相同的代碼段、數據段、堆和棧,但它們是各自獨立的進程,有不同的進程ID (PID)。在父進程中,fork()返回子進程的PID(正整數),在子進程中,fork()返回0,如果fork()調用失敗(例如系統資源不足),則返回-1,并設置errno以指示錯誤原因。

下面是一個符合UNIX標準的守護進程轉化函數的C語言實現,參考了《UNIX環境高級編程》中的經典步驟:

// daemonize/c/daemon.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <signal.h>

void daemonize()
{
    pid_t pid;

    // 1. Fork off the parent process 
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    // If we got a good PID, then we can exit the parent process.
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    // 2. Create a new session to become session leader to lose controlling TTY
    if (setsid() < 0) {
        exit(EXIT_FAILURE);
    }

    // 3. Fork again to ensure the process won't allocate controlling TTY in future
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    // 4. Change the current working directory to root.
    if (chdir("/") < 0) {
        exit(EXIT_FAILURE);
    }

    // 5. Set the file mode creation mask to 0.
    umask(0);

    // 6. Close all open file descriptors.
    for (int x = sysconf(_SC_OPEN_MAX); x>=0; x--) {
        close(x);
    }

    // 7. Reopen stdin, stdout, stderr to /dev/null
    open("/dev/null", O_RDWR); // stdin
    dup(0);                    // stdout
    dup(0);                    // stderr

    // Optional: Log the daemon starting
    openlog("daemonized_process", LOG_PID, LOG_DAEMON);
    syslog(LOG_NOTICE, "Daemon started.");
    closelog();
}

int main() {
    daemonize();

    // Daemon process main loop
    while (1) {
        // Perform some background task...
        sleep(30); // Sleep for 30 seconds.
    }

    return EXIT_SUCCESS;
}

注:這里省略了書中設置系統信號handler的步驟。

這里的daemonize函數完成了標準的守護化轉化過程,并確保了程序在后臺無依賴地穩定運行。我們編譯運行該程序后,程序進入后臺運行,通過ps命令可以查看到類似下面內容:

$ ./c-daemon-app 
$ ps -ef|grep c-daemon-app
root     28517     1  0 14:11 ?        00:00:00 ./c-daemon-app

我們看到c-daemon-app的父進程是ppid為1的進程,即linux的init進程。我們看到上面c代碼中轉化為守護進程的函數daemonize進行了兩次fork,至于為何要做兩次fork,在我的《理解Zombie和Daemon Process[4]》一文中有說明,這里就不贅述了。

那么Go是否可以參考上述步驟實現Go程序的守護進程轉化呢?我們接著往下看。

2. Go語言實現守護進程的挑戰

關于Go如何實現守護進程的轉換,在Go尚未發布1.0之前的2009年就有issue提到,在runtime: support for daemonize[5]中,Go社區與Go語言的早起元老們討論了在Go中實現原生守護進程的復雜性,主要挑戰源于Go的運行時及其線程管理方式。當一個進程執行fork操作時,只有主線程被復制到子進程中,如果fork前Go程序有多個線程(及多個goroutine)在執行(可能是由于go runtime調度goroutine和gc產生的線程),那么fork后,這些非執行fork線程的線程(以及goroutine)將不會被復制到新的子進程中,這可能會導致后續子進程中線程運行的不確定性(基于一些fork前線程留下的數據狀態)。

理想情況下是Go runtime提供類似的daemonize函數,然后在多線程啟動之前實現守護進程的轉化,不過Go團隊至今也沒有提供該機制,而是建議大家使用如systemd的第三方工具來實現Go程序的守護進程轉化。

既然Go官方不提供方案,Go社區就會另辟蹊徑,接下來,我們看看目前Go社區的守護進程解決方案。

3. Go社區的守護進程解決方案

盡管面臨挑戰,Go社區還是開發了一些庫來支持Go守護進程的實現,其中一個star比較多的解決方案是github.com/sevlyar/go-daemon。

go-daemon庫的作者巧妙地解決了Go語言中無法直接使用fork系統調用的問題。go-daemon采用了一個簡單而有效的技巧來模擬fork的行為:該庫定義了一個特殊的環境變量作為標記。程序運行時,首先檢查這個環境變量是否存在。如果環境變量不存在,執行父進程相關操作,然后使用os.StartProcess(本質是fork-and-exec)啟動帶有特定環境變量標記的程序副本。如果環境變量存在,執行子進程相關操作,繼續執行主程序邏輯,下面是該庫作者提供的原理圖:

圖片圖片

這種方法有效地模擬了fork的行為,同時避免了Go運行時中與線程和goroutine相關的問題。下面是使用go-daemon包實現Go守護進程的示例:

// daemonize/go-daemon/main.go

package main

import (
 "log"
 "time"

 "github.com/sevlyar/go-daemon"
)

func main() {
 cntxt := &daemon.Context{
  PidFileName: "example.pid",
  PidFilePerm: 0644,
  LogFileName: "example.log",
  LogFilePerm: 0640,
  WorkDir:     "./",
  Umask:       027,
 }

 d, err := cntxt.Reborn()
 if err != nil {
  log.Fatal("無法運行:", err)
 }
 if d != nil {
  return
 }
 defer cntxt.Release()

 log.Print("守護進程已啟動")

 // 守護進程邏輯
 for {
  // ... 執行任務 ...
  time.Sleep(time.Second * 30)
 }
}

運行該程序后,通過ps可以查看到對應的守護進程:

$make
go build -o go-daemon-app 
$./go-daemon-app 

$ps -ef|grep go-daemon-app
  501  4025     1   0  9:20下午 ??         0:00.01 ./go-daemon-app

此外,該程序會在當前目錄下生成example.pid(用于實現file lock),用于防止意外重復執行同一個go-daemon-app:

$./go-daemon-app
2024/09/26 21:21:28 無法運行:daemon: Resource temporarily unavailable

雖然原生守護進程化提供了精細的控制且無需安裝和配置外部依賴,但進程管理工具提供了額外的功能,如開機自啟[6]、異常退出后的自動重啟和日志記錄等,并且Go團隊推薦使用進程管理工具來實現Go守護進程。進程管理工具的缺點在于需要額外的配置(比如systemd)或安裝設置(比如supervisor)。

4. 小結

在Go中實現守護進程化,雖然因為語言運行時的特性而具有挑戰性,但通過社區開發的庫和謹慎的實現是可以實現的。隨著Go語言的不斷發展,我們可能會看到更多對進程管理功能的原生支持。同時,開發者可以根據具體需求,在原生守護進程化、進程管理工具或混合方法之間做出選擇。

本文涉及的源碼可以在這里[7]下載。

參考資料

[1] systemd: https://tonybai.com/2016/12/27/when-docker-meets-systemd

[2] supervisor: http://supervisord.org

[3] UNIX環境高級編程: https://book.douban.com/subject/25900403/

[4] 理解Zombie和Daemon Process: https://tonybai.com/2005/09/21/understand-zombie-and-daemon-process/

[5] runtime: support for daemonize: https://github.com/golang/go/issues/227

[6] 開機自啟: https://tonybai.com/2022/09/12/how-to-install-a-go-app-as-a-system-service-like-gitlab-runner

[7] 這里: https://github.com/bigwhite/experiments/tree/master/daemonize

[8] Gopher部落知識星球: https://public.zsxq.com/groups/51284458844544

[9] 鏈接地址: https://m.do.co/c/bff6eed92687

責任編輯:武曉燕 來源: TonyBai
相關推薦

2024-08-29 13:23:04

WindowsGo語言

2010-06-28 14:52:30

cron進程

2011-03-29 12:45:07

Zabbix進程

2017-04-11 16:00:40

Linuxsyslog進程

2010-03-02 16:37:53

Linux Quagg

2010-03-16 13:41:09

Python進程

2025-06-17 09:32:15

2024-02-21 08:33:27

GoReadDir性能

2009-11-24 11:35:59

2010-07-15 15:54:10

Perl守護進程

2025-05-29 08:10:00

Linux進程系統

2023-11-30 08:09:02

Go語言

2012-11-08 09:36:10

Google Go

2015-10-20 17:06:52

2013-01-15 15:18:46

Linux守護進程

2012-05-08 11:01:45

linux守護進程

2010-07-15 15:47:46

Perl守護進程

2021-07-26 09:47:38

Go語言C++

2011-08-08 10:02:55

iPhone開發 進程 通信

2018-01-02 16:39:04

點贊
收藏

51CTO技術棧公眾號

中文字幕日韩精品有码视频| 中文字幕日韩欧美一区二区三区| 97精品国产97久久久久久| 人妻丰满熟妇av无码久久洗澡| 欧美久久天堂| 国产女同互慰高潮91漫画| 91网站在线免费观看| 九九九国产视频| 波多野结衣在线观看一区二区三区| 欧美日韩成人一区| 人妻久久久一区二区三区| av在线播放网站| 国产91精品露脸国语对白| 日本欧美爱爱爱| 久久久精品视频免费观看| 综合色就爱涩涩涩综合婷婷| 欧美喷潮久久久xxxxx| 无码熟妇人妻av在线电影| 都市激情一区| www.激情成人| 97免费高清电视剧观看| 中文字幕欧美人妻精品一区蜜臀 | 老司机午夜精品视频| www.欧美免费| 欧美做受xxxxxⅹ性视频| 网站一区二区| 91 com成人网| 无码少妇一区二区三区芒果| 成人女同在线观看| 国产精品短视频| 人偷久久久久久久偷女厕| 免费观看黄一级视频| 国产揄拍国内精品对白| 国产精品大片wwwwww| 欧美一二三区视频| 国产一区二区三区四区老人| 精品国产拍在线观看| 亚洲第一综合网| 亚洲欧美成人vr| 亚洲第一色中文字幕| 男男受被啪到高潮自述| 亚洲青青一区| 欧美日韩亚洲综合在线| 少妇性l交大片| 亚洲天堂资源| 色综合网色综合| 日韩中文字幕三区| 国产伦子伦对白在线播放观看| 一区二区在线观看免费视频播放| 中文字幕99| 色影院视频在线| 国产精品色婷婷久久58| 日韩国产一区久久| 高清在线观看av| 久久精品综合网| 欧洲一区二区在线观看| 欧美扣逼视频| 国产拍揄自揄精品视频麻豆| 欧美一区二区影视| 国产粉嫩一区二区三区在线观看| 久久久精品免费网站| 欧美一区亚洲二区| 国产乱视频在线观看| 国产欧美一区在线| 久久综合久久久| 四虎在线视频| 国产三级欧美三级日产三级99| 日韩精品久久久| 五月天婷婷在线视频| 中文字幕一区二区三区蜜月| 亚洲成年人专区| 青春草免费在线视频| 夜夜精品视频一区二区| 夜夜添无码一区二区三区| 色综合亚洲图丝熟| 欧美四级电影网| 国产女同无遮挡互慰高潮91| 一区二区三区高清在线观看| 亚洲电影免费观看高清完整版在线观看| www国产视频| 免费成人结看片| 日韩中文字幕视频| 久久99爱视频| 欧美影院久久久| 日本高清www免费视频| 国产精品日韩| 国产精品久久二区| 国产一区二区波多野结衣 | 亚洲精品乱码久久久久久自慰| 国产超碰精品| 91精品国产黑色紧身裤美女| 国产精品扒开腿做爽爽爽a片唱戏| 男人的天堂久久| 曰本色欧美视频在线| 成人免费毛片xxx| 国产欧美亚洲一区| 国产一区二区在线免费视频| 蜜桃91麻豆精品一二三区| 久久久www成人免费无遮挡大片| 一区二区三区三区在线| 阿v视频在线| 欧美福利视频导航| 国产熟妇搡bbbb搡bbbb| 97在线精品| 91精品国产高清自在线看超| 在线播放一级片| 99久久国产综合色|国产精品| 亚洲精品乱码久久久久久蜜桃91| 伊人福利在线| 欧美在线影院一区二区| 在线播放第一页| 日本一区二区高清不卡| 91精品国产99| 国产精品污视频| 久久久99精品免费观看| 日本五级黄色片| 激情久久一区二区| 国产视频在线一区二区| 麻豆视频在线观看| 久久av资源站| 欧美性天天影院| 99热99re6国产在线播放| 欧美高清视频一二三区| 亚洲一区二区自偷自拍| 国产免费成人| 国产精品三区www17con| 2024最新电影免费在线观看| 欧美色窝79yyyycom| 一卡二卡三卡四卡| 伊人久久亚洲热| 97netav| 女女色综合影院| 欧美性猛交一区二区三区精品| 熟女丰满老熟女熟妇| 99riav1国产精品视频| 91精品国产综合久久久久久丝袜| 午夜毛片在线| 欧美另类高清zo欧美| 日本美女bbw| 日韩专区中文字幕一区二区| 久久亚洲一区二区| 成人片免费看| 国产午夜精品久久久 | **亚洲第一综合导航网站| 在线视频1区2区| 欧美午夜一区二区三区| 熟女高潮一区二区三区| 午夜亚洲影视| 欧美1o一11sex性hdhd| 麻豆国产在线| 精品在线欧美视频| 99精品人妻国产毛片| 久久欧美一区二区| 国产免费999| 欧美中文字幕一区二区| 国产精品久久久久不卡| sese一区| 91精品国产91久久久久久一区二区 | 久久这里只精品最新地址| 久久黄色片视频| 欧美成人专区| 国产成人精品久久亚洲高清不卡| 福利在线视频导航| 欧美日韩一区二区三区高清| 二区三区四区视频| 国产精品1区2区3区| 男人添女人下部视频免费| 成人午夜三级| 2021国产精品视频| jizz在线观看中文| 欧美一区二区成人| 日韩精品一卡二卡| 久久精品亚洲乱码伦伦中文| 亚洲欧美国产日韩综合| 欧美淫片网站| 国内精品二区| 成人国产激情| 色综合久久88色综合天天看泰| 黄色www视频| 日本丶国产丶欧美色综合| 午夜剧场免费在线观看| 成人动漫一区二区三区| 久草在在线视频| 中文字幕亚洲综合久久五月天色无吗'' | 白白色亚洲国产精品| 中文字幕无码不卡免费视频| 99久久久国产精品美女| 国产欧美亚洲日本| 朝桐光一区二区| 欧美另类精品xxxx孕妇| 手机看片福利在线观看| 欧美精品xxxxbbbb| www.天天色| 中文字幕佐山爱一区二区免费| 亚洲精品激情视频| 日本不卡123| 日韩久久久久久久久久久久| 国产欧美亚洲精品a| 91久久久一线二线三线品牌| a日韩av网址| 久久91超碰青草是什么| 不卡在线视频| 亚洲国产欧美精品| 国产精品国产三级国产aⅴ| 激情久久av一区av二区av三区| 女教师淫辱の教室蜜臀av软件| 成人午夜精品在线| 成人蜜桃视频| 国产天堂第一区| 亚洲美女视频在线| www.自拍偷拍| 欧美高清视频一二三区 | 国产精品成人69xxx免费视频| 看片的网站亚洲| 成年人看的毛片| 成人久久一区| 中文字幕一区二区三区蜜月| 国产三级精品三级在线| 久久av在线| 91视频 - 88av| 成人羞羞网站| 欧美日韩电影一区二区三区| ccyy激情综合| 亚洲精品日韩av| 电影在线观看一区二区| 国产亚洲毛片在线| 亚洲成色www久久网站| 国产精品毛片久久久| 91欧美激情另类亚洲| 日本福利午夜视频在线| 亚洲黄色小视频| 日本少妇xxxxx| av一区二区三区四区| 亚洲三级在线观看视频| 日韩不卡一区二区| 久久精品99国产| 一本久久知道综合久久| 日本人体一区二区| 久久中文资源| 亚洲精品中文字幕av| 国产精品亚洲lv粉色| 色综合久久天天综合网| 日韩手机在线观看| 一区二区免费在线| 久久久精品国产sm调教| 一区二区三区欧美在线观看| 青娱乐国产在线| 亚洲国产综合色| 鲁丝一区鲁丝二区鲁丝三区| 国偷自产视频一区二区久| 国产成人免费电影| 国产成人tv| 精品一区久久久久久| 特黄特色欧美大片| 欧美日韩在线一二三| 精品国产精品久久一区免费式| 日本午夜精品一区二区| 日韩精品免费一区二区在线观看 | 亚洲欧美激情另类| 亚洲成人aaa| 欧美日韩在线精品一区二区三区激情综| 亚洲精品一区二区网址| 国产女主播在线直播| 北条麻妃久久精品| 污污视频在线看| 97热在线精品视频在线观看| 成人av免费电影网站| 国产精品成av人在线视午夜片 | 老司机精品影院| 欧美精品亚州精品| 国模私拍一区二区国模曼安| 欧美壮男野外gaytube| jizz久久久久久| 91视频99| 曰本一区二区三区视频| 一区在线电影| 国产一区亚洲| 亚洲爆乳无码专区| 国产真实乱子伦精品视频| 成年女人免费视频| 国产午夜精品一区二区三区四区| 亚洲一级理论片| 亚洲一区精品在线| 欧美一级黄视频| 日韩精品一区二区在线| 青青草视频在线免费观看| 精品国产网站地址| 乱馆动漫1~6集在线观看| 中文字幕一区二区三区视频| 成人免费无码av| 国产麻豆成人精品| 亚洲天堂久久新| 亚洲少妇屁股交4| 成人午夜视频精品一区| 欧美人牲a欧美精品| 天天射,天天干| 色偷偷91综合久久噜噜| 国产99在线| 91色精品视频在线| 最新国产一区| av一区二区三区免费观看| 日本aⅴ免费视频一区二区三区 | 中文字幕亚洲欧美日韩高清| 国产99re66在线视频| 国产精品大陆在线观看| 久久婷婷国产| 日本一道在线观看| 日本美女视频一区二区| 白嫩情侣偷拍呻吟刺激| 亚洲视频免费在线| 最近中文字幕在线观看| 日韩成人在线网站| 免费在线中文字幕| 国产一区二区香蕉| 国产探花在线精品一区二区| 日韩网站在线免费观看| 国产揄拍国内精品对白| 免费黄色在线网址| 色999日韩国产欧美一区二区| 欧美一级视频免费| 欧美激情极品视频| 国产精品久久久久久久久久辛辛| 日韩欧美视频第二区| 国产精品夜夜夜| 国产极品一区二区| 香蕉成人伊视频在线观看| 国产99视频在线| www.日韩av.com| 免费一区二区三区四区| 日本在线成人一区二区| 男女精品视频| 青青草视频播放| 欧美日韩人人澡狠狠躁视频| 黄色一级大片在线免费看国产| 欧美乱大交xxxxx| 懂色av色香蕉一区二区蜜桃| 自拍另类欧美| 久久精品国内一区二区三区| 亚洲精品国产精品乱码在线观看| 欧美在线视频全部完| 国产精品久久久久一区二区国产 | 久久av网站| 神马午夜伦理影院| 国产精品一区二区在线观看网站 | 疯狂做受xxxx高潮欧美日本| 婷婷色在线视频| 97超碰色婷婷| 伊人春色之综合网| 韩国日本美国免费毛片| 国产婷婷色一区二区三区| 久久这里只有精品9| 在线日韩av观看| 青青国产精品| 国产日韩欧美大片| 丁香婷婷综合激情五月色| 久久久.www| 日韩成人中文字幕在线观看| 亚洲最大网站| 亚洲国产一区在线| 国产剧情一区在线| 国产亚洲精品久久久久久打不开| 亚洲精品第一页| 在线观看精品| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 极品少妇xxxx偷拍精品少妇| 欧美极品aaaaabbbbb| 日韩电影中文字幕一区| 日韩av首页| 久久久久久久久影视| 成人黄色在线网站| 无码人妻精品一区二区50| 日日摸夜夜添一区| av不卡一区二区| 黄色片一级视频| 国产精品久久久久久久蜜臀| 99久久久久久久| 91精品国产91久久久久久不卡| 成人三级视频| 一二三区视频在线观看| 欧美午夜精品久久久久久人妖 | 亚洲不卡视频在线| 亚洲免费观看高清完整版在线观看熊 | 熟女俱乐部一区二区| 91麻豆精品国产91久久久| bbw在线视频| 亚洲一区3d动漫同人无遮挡| 懂色一区二区三区免费观看| 波多野结衣小视频| 欧美国产精品日韩| 欧美色图在线播放| 无码国产精品一区二区免费式直播 | 蜜臀av.com| 2020日本不卡一区二区视频| 91精品在线视频观看| 78色国产精品| 影音先锋日韩精品| 男人操女人动态图| 亚洲成人黄色在线观看| 色综合视频一区二区三区日韩| 欧美日韩性生活片|