V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Jerry23333
V2EX  ›  Go 编程语言

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

  •  
  •   Jerry23333 · 2023-06-02 09:58:59 +08:00 · 1384 次点击
    这是一个创建于 575 天前的主题,其中的信息可能已经有所发展或是发生改变。

    初学 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 感觉像是什么都没有做一样,不知道我的感觉是否正确?

    9 条回复    2023-06-02 17:48:21 +08:00
    ho121
        1
    ho121  
       2023-06-02 10:27:59 +08:00
    没写过 go ,不过大概猜测 Release 是回收子进程,防止僵尸进程的出现。建议看看僵尸进程的相关文章。
    Jerry23333
        2
    Jerry23333  
    OP
       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
        3
    ysc3839  
       2023-06-02 10:44:27 +08:00 via Android   ❤️ 1
    在 Windows 下会关闭 Process Handle
    flyqie
        4
    flyqie  
       2023-06-02 10:45:58 +08:00 via Android
    用完就释放是个好习惯。

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

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

    在任何语言都是这样的。

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

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

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

    gc 终究不能胜任所有情况,有些时候保持这种好习惯能避免很多麻烦事。
    PTLin
        9
    PTLin  
       2023-06-02 17:48:21 +08:00
    unix 下没有任何用,就是简单的把 pid 设置成了-1 ,然后清理了一下 Finalizer ,并且你不调用这个方法这个对象在 gc 回收的时候也会调用这个 Release
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2772 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:02 · PVG 18:02 · LAX 02:02 · JFK 05:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.