当前位置: 首页 > 工具软件 > GO daemon > 使用案例 >

Go创建daemon程序

张权
2023-12-01

daemon的概念

守护进程(daemon)就是一直在后台运行的进程,它没有控制终端,无法和前台的用户交互。当我们打开一个终端时会创建一个session会话(shell),从用户登录开始到用户退出为止,这段时间内在该终端执行的进程都属于这一个会话。一个会话一般包含一个前台进程组、一个后台进程组和一个会话首进程(shell程序本身)。 例如用以下命令启动5个进程:

$ proc1 | proc2 &

$ proc3 | proc4 | proc5

proc1和proc2属于同一个后台进程组,proc3、proc4、proc5属于同一个前台进程组,Shell进程本身属于一个单独的进程组。这些进程组的控制终端相同,它们属于同一个session。 "后台任务"与"前台任务"的本质区别只有一个:是否继承标准输入。后台任务不再继承当前 session 的标准输入(stdin),你无法向后台任务输入指令了,但是后台任务继承了标准输出(stdout)和标准错误(stderr)后台任务的所有输出依然会同步地在命令行下显示

当终端关闭或者检测到网络连接断开时会将挂断信号(SIGHUP)发送给终端控制进程(会话期首进程,shell进程)。如果会话期首进程接收到SIGHUP信号后会终止,会同时给前台进程组发送SIGHUP信号(进程接收到SIGHUP信号默认处理是退出),shell的 huponexit参数

(shopt | grep huponexit)

决定了shell退出时是否发送SIGHUP信号给后台进程组。

如何实现守护进程

守护进程要与从启动它的父进程(一般是shell程序)的运行环境隔离开来,需要处理的内容大致包括会话、控制终端、进程组、文件描述符、文件权限掩码以及工作目录等。 ``` void init daemon() { pidt pid; int i = 0; // 1. 创建子进程,父进程退出,父进程退出子进程变成孤儿进程,孤儿进程由init进程(pid为1)收养 if ((pid = fork()) == -1) { printf("Fork error !\n"); exit(1); } if (pid != 0) { exit(0); // 父进程退出 }

// 2. 子进程调用 setsid创建新会话,成为成为会话首进程,并且子进程成为一个新进程组的组长进程,而新的会话也脱离了控制终端的控制。 //(组长进程调用 setsid会出错,所以第一步fork出子进程,fork出的子进程一定不会是组长进程) setsid();

//3. 子进程变成无终端的会话首进程,但是它仍然可以重新申请打开一个控制终端。可以通过再次创建子进程结束当前进程,使进程不再是会话首进程来禁止进程重新打开控制终端。 if ((pid = fork()) == -1) { printf("Fork error !\n"); exit(-1); } if (pid != 0) { exit(0);

} //4. 改变当前目录为根目录,重设文件权限掩码,关闭文件描述符 //因为这几样东西都是继承自父进程的 chdir("/tmp"); // 改变工作目录 umask(0); // 重设文件掩码 for (; i < getdtablesize(); ++i) { close(i); // 关闭打开的文件描述符 }

return;

}

```

go语言如何实现守护进程

目前Go程序还不能实现daemon,因为go程序在启动时runtime可能会创建多个线程(用于内存管理,垃圾回收,goroutine管理等),而fork并不能处理好拥有多个线程的进程。

`
d := flag.Bool("d", false, "Whether or not to launch in the background(like a daemon)")
if *d {
cmd := exec.Command(os.Args[0],
"-close-fds",
)
serr, err := cmd.StderrPipe()
if err != nil {
log.Fatalln(err)
}
err = cmd.Start()
if err != nil {
log.Fatalln(err)
}
s, err := ioutil.ReadAll(serr)
s = bytes.TrimSpace(s)
if bytes.HasPrefix(s, []byte("addr: ")) {
fmt.Println(string(s))
cmd.Process.Release()
} else {
cmd.Process.Kill()
}
bjhxdtwx.cn
ledcontrol.cn
jnygtz.cn
e2424.cn
gamez5.cn
bzdzbj.cn
szantr8.cn
labelshop.cn
jsqygl.cn
bjtsd.cn
tianjindaiyun.cn
daiyun520.cn
wjtouzi.cn
sjsdmw.cn
tyhxdz.cn
sdcdcm.cn
decohua.cn
ioooi.cn
huangguan0051.cn
jinshaylc10086.cn
cnlogistics.cn
huguenot.cn
cevf.cn
h5700.cn
caffekenon.cn
hflhk.cn
toysky.cn
baiwf.cn
shwyprint.cn
0756com.cn
ecocooling.cn
syyinhang.cn
ylttw.cn
km-ups.cn
clinica.cn
h5818.cn
ti-zone.cn
zjwdw.cn
345609.cn
lkhsht.cn
lejiacn.cn
57maiche.cn
gzhxy.cn
yinuohk.cn
gfbhys.cn
yyjzl.cn
giftcenter.cn
fizconz.cn
fangzhendongwu.cn
liyiqiandian.cn
chenchaoming.cn
hthstzzx.cn
dongbeimao.cn
inanshen.cn
organicbeauty.cn
simandl.cn
93net.cn
guangzizhifu.cn
ghc123.cn
fetiontel.cn
fuboke.cn
amazonfirestore.cn
qqhrqc.cn
paipaizhao.cn
lindanle.cn
8fdc.cn
lcaozhankh.cn
lcaozhandm.cn
lcaozhanwv.cn
xayyjzl.cn
hnzjtz.cn
hg01024.cn
mir666.cn
hg01022.cn
ruxianjiankang.cn
lcaozhanmu.cn
591jieyan.cn
rhrbzs.cn
jsfdj.cn
zddic.cn
bjwhjy.cn
egowu.cn
dyrszs.cn
vestebene.cn
corbus.cn
newshidai.cn
5fdc.cn
sektanwei.cn
lcaozhanrv.cn
tiaong.cn
cqtanwei.cn
51funwen.cn
ccldjx.cn
nursestation.cn
tjspl.cn
loveapril.cn
hg01003.cn
tzxuanle.cn
rmlkb.cn
bujijuan.cn
cz111.cn }

`

使用Supervisord

 类似资料: