Tac say

只想做个程序演奏家

Golang, Cmd会泄露文件句柄

在go中用cmd生成新的process时, 在某些os中(包括linux的某些版本), 父进程的文件句柄会泄露到子进程中, 参看代码

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    a, _ := os.OpenFile("1", os.O_CREATE|os.O_RDWR, 0755)
    defer a.Close()
    cmd := exec.Command("sh", "-c", "lsof +D .; sleep 3")
    output, _ := cmd.CombinedOutput()
    fmt.Printf("%v\n", string(output))
}

得到输出

[root@GroupH-HA-1 tmp]# uname -a
Linux GroupH-HA-1 2.6.18-194.el5xen #1 SMP Tue Mar 16 22:01:26 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
[root@GroupH-HA-1 tmp]# ./main
COMMAND  PID USER   FD   TYPE DEVICE    SIZE    NODE NAME
bash    4693 root  cwd    DIR  253,0   32768 3506177 .
main    6184 root  cwd    DIR  253,0   32768 3506177 .
main    6184 root  txt    REG  253,0 2250464 3506237 ./main
main    6184 root    3u   REG  253,0       0 3506238 ./1
sh      6189 root  cwd    DIR  253,0   32768 3506177 .
sh      6189 root    3u   REG  253,0       0 3506238 ./1
lsof    6190 root  cwd    DIR  253,0   32768 3506177 .
lsof    6191 root  cwd    DIR  253,0   32768 3506177 .

可以看到./1的文件句柄泄漏到了sh -c中, 目前为止没有特别好的解决方案

参看此处bug描述

Comments