process.Release() 的作用究竟是什么

2023-06-02 09:58:59 +08:00
 Jerry23333

初学 go ,最近在阅读 wireguard-go 的代码,看到其 daemonize 相关的代码,其中有如下代码段(去掉无关代码):

		path, err := os.Executable()
		if err != nil {
			fmt.Printf("Failed to determine executable: %v\n", err)
			os.Exit(-1)
		}

		process, err := os.StartProcess(
			path,
			os.Args,
			attr,
		)
		if err != nil {
			fmt.Printf("Failed to daemonize: %v\n", err)
			os.Exit(-1)
		}
		fmt.Printf("chile process pid is %v\n", process.Pid)

		err = process.Release()
		if err != nil {
			fmt.Printf("release process failed %v\n", err)
		}

其中 process.Release() 究竟 Release 了什么,注释中提到的是:"Release releases any resources associated with the Process p, rendering it unusable in the future." ,这其中resources 指的是什么?

github中也有相关的 Issues ,提到“ I've sent the PR that specifying Release's NOOP behavior on Unix.” 其中 "NOOP" 是什么意思? NO operation 什么都不做吗?

我简单试验了一下,如果父进程执行完创建进程后立刻退出了,不管是否进行 Release , 子进程都会被托管给 launchd 进程。

而如果父进程没有立即退出,进行了 Release ,这时候子进程的父进程就是创建他的进程如果子进程先退出,此时子进程就会变成一个僵尸进程。不进行 Release 的结果也是一样的。

我感到非常的混乱,Release 感觉像是什么都没有做一样,不知道我的感觉是否正确?

1369 次点击
所在节点    Go 编程语言
9 条回复
ho121
2023-06-02 10:27:59 +08:00
没写过 go ,不过大概猜测 Release 是回收子进程,防止僵尸进程的出现。建议看看僵尸进程的相关文章。
Jerry23333
2023-06-02 10:40:57 +08:00
感谢您的回复,我起初也是觉得 Release 是防止出现僵尸进程的,但我测试了下 不管有没有 Release ,子进程退出以后都会变成僵尸进程,如 91566 。

```bash
91563 ttys000 0:00.01 ./main -t
91566 ttys000 0:00.00 <defunct>
```
ysc3839
2023-06-02 10:44:27 +08:00
在 Windows 下会关闭 Process Handle
flyqie
2023-06-02 10:45:58 +08:00
用完就释放是个好习惯。

你不能假定底层会做什么,但起码你可以把你能做的都给做了。

哪怕底层现在是 NOOP ,后期也可能会更改(况且还要考虑到跨平台),为了保证代码的可靠性,最好从一开始就把能做的都给做了,这样能避免很多问题。

在任何语言都是这样的。

有 gc 的话尽量(不是全部,那不是你应该做的)减少 gc 的工作,来优化性能,gc 适用的是普遍环境,某些特殊情况下 gc 做的优化可能并不咋地。

没有 gc 的话只能自己处理,总不能全在进程退出的时候由系统处理吧?
Jerry23333
2023-06-02 11:16:51 +08:00
@flyqie 结合您和 @ysc3839 回复的内容,我的理解是在 Windows 下会关闭 process handle ,但是在 unix 下该函数其实什么也不做,为了良好的编程习惯以及潜在的跨平台可能,通常还是要有该代码。
harrozze
2023-06-02 11:17:27 +08:00
@flyqie #4 C 语言入门的程序员可能会有这习惯,写好 malloc 就去在合适的地方放个 free 。从自带 gc 语言入门的,这方面意识可能不强,或者得是到后期考虑到优化和防漏才会逐步加强吧。
hingle
2023-06-02 11:18:31 +08:00
@czy0538 我一般会开个 goroutine 调用 Wait() 让子进程退出后自动释放资源。
flyqie
2023-06-02 11:21:26 +08:00
@harrozze #6

是的,个人觉得不带 gc 的语言更能培养开发中的好习惯。

gc 终究不能胜任所有情况,有些时候保持这种好习惯能避免很多麻烦事。
PTLin
2023-06-02 17:48:21 +08:00
unix 下没有任何用,就是简单的把 pid 设置成了-1 ,然后清理了一下 Finalizer ,并且你不调用这个方法这个对象在 gc 回收的时候也会调用这个 Release

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/945133

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX