需要做一个服务在后台运行,又不想使用第三方进程管理工具,在网上找到一段代码,试了一下可以后台运行,不明白原理
package main
import (
	"log"
	"os"
	"os/exec"
	"strconv"
	"time"
)
func main() {
	args := os.Args
	daemon := false
	for k, v := range args {
		if v == "-d" {
			daemon = true
			args[k] = ""
		}
	}
	if daemon {
		Daemonize(args...)
		return
	}
	file, err := os.OpenFile("test.txt", os.O_CREATE|os.O_RDWR, 0664)
	if err != nil {
		log.Println(err)
		return
	}
	defer file.Close()
	for {
		file.Write([]byte(strconv.Itoa((int)(time.Now().Unix())) + "\n"))
		time.Sleep(time.Second * 1)
	}
}
func Daemonize(args ...string) {
	var arg []string
	if len(args) > 1 {
		arg = args[1:]
	}
	cmd := exec.Command(args[0], arg...)
	cmd.Env = os.Environ()
	cmd.Start()
}
后台运行 ./mian -d
|  |      16IbA2bj5ip3tK49j      2021-09-01 14:14:19 +08:00 里面有个 for 循环啊。 | 
|  |      2Dockerfile      2021-09-01 14:16:25 +08:00  11 你是我见过现实中第一个把 main 打成 mian 的( | 
|  |      3pkoukk      2021-09-01 14:16:55 +08:00 for{}死循环啊 | 
|      4hingbong      2021-09-01 14:20:33 +08:00 他相当于用命令行重新启动了一次自己,然后就 return 了 | 
|  |      5zjyl1994      2021-09-01 14:22:30 +08:00 for 循环啊朋友 for { file.Write([]byte(strconv.Itoa((int)(time.Now().Unix())) + "\n")) time.Sleep(time.Second * 1) } | 
|  |      6indexphp      2021-09-01 14:22:34 +08:00 上面说 for 循环的,仔细看看在传入 `-d` 的时候真的有走到 for 循环? | 
|      8PeterYang1996 OP @hingbong 应该是这样 | 
|      9PeterYang1996 OP @indexphp 你别理他们了 | 
|      10opsll      2021-09-01 14:45:00 +08:00  7 我的理解是这样的: cmd := exec.Command(args[0], arg...)这行代码,是将当前可执行文件,通过子进程的再启动一遍,后续执行 return 的时候主进程就退出了,而子进程就变成了孤儿进程,在后台执行。由于你这里有个 for 循环,那么就会在后台一直执行不退出。 | 
|  |      12Akiya      2021-09-01 16:43:07 +08:00 这个就是 Daemonize 的标准做法啊,起一个子进程去跑,然后自己无了,那么就是在后台运行了。很多软件比如 nginx 实现就是这样的 | 
|  |      13ysc3839      2021-09-01 16:55:38 +08:00 cmd := exec.Command(args[0], arg...) cmd.Env = os.Environ() cmd.Start() 就是再次启动了自身。 | 
|  |      14ysc3839      2021-09-01 17:13:11 +08:00 @ysc3839 这么做有用的根本原因大概是 shell 只会等待子进程,不会等待子进程启动的孙进程,所以子进程启动一个新进程后自己退出,shell 就不会等待了。如果遇到了会等孙进程的 shell 或终端,这种做法就无效了。 | 
|      17darknoll      2021-09-01 21:41:11 +08:00 居然有好几个说 for 循环的。。。 | 
|  |      18lululau      2021-09-01 22:33:18 +08:00 这个代码怎么说呢。。。知道 daemonize 这个词,竟然不知道 Google 一下 “How to make a daemon process in golang”,了解一下怎么正确编写 daemonize 代码 | 
|  |      19wangsongyan      2021-09-01 22:45:04 +08:00 via iPhone @darknoll #17 没 for 循环能后台运行? | 
|      20JustLookBy      2021-09-01 23:08:43 +08:00 @wangsongyan 后台运行和 for 循环 有一毛钱关系,for 循环和 time.Sleep(一万年) 在这作用一样,都只是模拟长时间运行而已。。。 | 
|  |      21wangsongyan      2021-09-02 06:54:14 +08:00 via iPhone @JustLookBy #20 你要这么说,我的回复少了两个字,没 for 循环能(一直)后台运行? | 
|  |      22ihipop      2021-09-02 08:01:05 +08:00 via Android @wangsongyan 能,包括但不限于 sleep channel,等方法 | 
|      24darknoll      2021-09-02 09:05:38 +08:00 @wangsongyan 你到现在还没明白这段代码的要点? | 
|      25bing0      2021-09-02 09:39:14 +08:00 那么问题来了,僵尸进程会内存溢出吗? | 
|      26lolizeppelin      2021-09-02 11:34:15 +08:00 找资料学把 fork  setsid setuid setgid 和信号 搞清楚,别走 cmd 这种邪门歪道 实在不想学你还可以直接用 systemd 来管 但是无论怎么搞 标准做法还是要处理信号来方便退出 | 
|  |      27cenbiq      2021-09-02 12:31:34 +08:00 不太理解前面说的孤儿进程,我直接启动进程就执行 for 不能做到吗?一定要启动子进程再让自身 return 才行? | 
|  |      28koolob      2021-09-02 12:52:16 +08:00 @cenbiq #27 直接启动然后 for 的话,此时控制台退出,程序就中断了。后台运行的目的是实现在控制台启动程序后,控制台退出,程序依然运行。 | 
|  |      29koolob      2021-09-02 12:54:51 +08:00 用这种做法还需要配套方案才行,比如保存进程号,处理各种信号,这样才能算是稳定的程序。只是本地练习的话倒是无所谓。 | 
|      30mxT52CRuqR6o5      2021-09-02 15:22:43 +08:00 问:水为什么会往低处流? 答:因为低处的位置比高处低。 | 
|      31mxT52CRuqR6o5      2021-09-02 15:29:40 +08:00 @cenbiq “后台”运行 | 
|      32barathrum      2021-09-02 16:07:35 +08:00 就是 double fork | 
|  |      33ragnaroks      2021-09-02 22:42:10 +08:00 看到上面几个 for 循环我一下以为我从小学开始学的 C 路走歪了,一般都是起个线程,主线程等待子线程结束,最简单的实现 | 
|  |      34lasuar      2021-09-03 11:08:36 +08:00 套娃,多此一举。 ./main & | 
|      35jianjian714      2021-09-03 14:50:31 +08:00 go 热重启算后台运行的一个完善的应用了吧 | 
|  |      36necodba      2021-09-16 19:04:34 +08:00 article-spider 里面能不能加一个并发。或者限定每一条获取数据的时间频率,另外如果首页的地址是 /article/1 , 第二页地址是 /pages?=2&type=commic&article=11,这种翻页完全改了参数的咋整 | 
|      37PeterYang1996 OP @necodba 你的 issue 这么提到这里了。。 | 
|      38PeterYang1996 OP |