Go Syscall
原文链接: Go Syscall
Golang-too_many_open_files
// 方式一:
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Cur: 1000000, Max: 1000000}); err != nil {
panic(err)
}
//方式二:
var rlimit syscall.Rlimit
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit)
if err != nil {
fmt.Println("get rlimit error: " + err.Error())
os.Exit(1)
}
rlimit.Cur = 50000 //以字节为单位
rlimit.Max = rlimit.Cur + 1024
err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit)
if err != nil {
fmt.Println("set rlimit error: " + err.Error())
os.Exit(1)
}
使用 go build 编译后,需要以 root 权限运行。
Killing a child process and all of its children in Go
Go是使用kill(2)向sh进程的PID发了一个KILL信号,但没有发给watch进程,sh进程被kill之后,导致watch进程变成孤儿进程。实际这是unix编程语言的一个非常正常的行为,只是...在很多场景下确实不适用。
- 解决方案
kill(2)不但支持向单个PID发送信号,还可以向进程组发信号,传递进程组PGID的时候要使用负数的形式。我们只要把sh进程及其所有子进程放到一个进程组里,就可以批量Kill了。关键是PGID的设置,默认情况下,子进程会把自己的PGID设置成与父进程相同,所以,我们只要设置了sh进程的PGID,所有子进程也就相应的有了PGID。
package main
import (
"fmt"
"os/exec"
"syscall"
"time"
)
func main() {
cmd := exec.Command("/bin/sh", "-c", "watch date > date.txt")
// Go会将PGID设置成与PID相同的值,防止sh进程结束后,watch进程变成孤儿进程
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
start := time.Now()
time.AfterFunc(3*time.Second, func() { syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) })
err := cmd.Run()
fmt.Printf("pid=%d duration=%s err=%s\n", cmd.Process.Pid, time.Since(start), err)
}