为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 golang 程序设置 ulimit -n?

如何从 golang 程序设置 ulimit -n?

Go
ABOUTYOU 2021-06-15 09:08:35
我的目的是在 golang 程序中设置 ulimit -n,这样我就不必全局设置它,而是在程序中限制它。发现系统调用 setrlimit 和 get rlimit 相同。( http://linux.die.net/man/2/setrlimit )但是当我尝试相同的示例程序时,我在设置值时收到一条错误消息,指出无效参数。package mainimport (    "fmt"    "syscall")func main() {    var rLimit syscall.Rlimit    err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)    if err != nil {        fmt.Println("Error Getting Rlimit ", err)    }    fmt.Println(rLimit)    rLimit.Max = 999999    rLimit.Cur = 999999    err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)    if err != nil {        fmt.Println("Error Setting Rlimit ", err)    }    err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)    if err != nil {        fmt.Println("Error Getting Rlimit ", err)    }    fmt.Println("Rlimit Final", rLimit)}得到的输出是:george@george-Not-Specified ~/work/odesk/progium/trial $ ./getRlimit {4294963002032703 0}Error Setting Rlimit  invalid argumentRlimit Final {4294963002032703 999999}george@george-Not-Specified ~/work/odesk/progium/trial $ sudo ./getRlimit [sudo] password for george: {4294963002032703 0}Error Setting Rlimit  invalid argument Rlimit Final {4294963002032703 999999}george@george-Not-Specified ~/work/odesk/progium/trial $ uname -aLinux george-Not-Specified 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linuxgeorge@george-Not-Specified ~/work/odesk/progium/trial $ 所以我能够得到 rlimit 设置限制失败并返回错误。即使它失败了,当我再次取值时 MAX 值发生了变化,但 CUR 值保持不变。这个错误是由于我的内核有问题还是一个坏程序?我在哪里可以找到更多信息以及如何处理此类问题?
查看完整描述

1 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

它按预期工作。


setrlimit(2)。


软限制是内核为相应资源强制执行的值。硬限制充当软限制的上限:非特权进程只能将其软限制设置为从 0 到硬限制范围内的值,并且(不可逆转地)降低其硬限制。特权进程(在 Linux 下:具有 CAP_SYS_RESOURCE 功能的进程)可以对任一限制值进行任意更改。


rlimit.go:


package main


import (

    "fmt"

    "syscall"

)


func main() {

    var rLimit syscall.Rlimit

    err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)

    if err != nil {

        fmt.Println("Error Getting Rlimit ", err)

    }

    fmt.Println(rLimit)

    rLimit.Max = 999999

    rLimit.Cur = 999999

    err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)

    if err != nil {

        fmt.Println("Error Setting Rlimit ", err)

    }

    err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)

    if err != nil {

        fmt.Println("Error Getting Rlimit ", err)

    }

    fmt.Println("Rlimit Final", rLimit)

}

输出:


$ uname -a

Linux peterSO 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:43:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

$ go build rlimit.go

$ ./rlimit

{1024 4096}

Error Setting Rlimit  operation not permitted

Rlimit Final {1024 4096}

$ sudo ./rlimit

[sudo] password for peterSO:

{1024 4096}

Rlimit Final {999999 999999}

更新:


我成功跑rlimit.go了linux/amd64,你失败了linux/386。有一个围棋的bug Getrlimit,并Setrlimit为Linux 32位的分布。这些错误已得到修复。


使用 Godefault分支tip(包括错误修复),运行以下命令,并使用结果更新您的问题。


$ uname -a

Linux peterSO 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:46:08 UTC 2013 i686 i686 i686 GNU/Linux

$ go version

go version devel +ba52f6399462 Thu Jul 25 09:56:06 2013 -0400 linux/386

$ ulimit -Sn

1024

$ ulimit -Hn

4096

$ go build rlimit.go

$ ./rlimit

{1024 4096}

Error Setting Rlimit  operation not permitted

Rlimit Final {1024 4096}

$ sudo ./rlimit

[sudo] password for peterSO: 

{1024 4096}

Rlimit Final {999999 999999}


查看完整回答
反对 回复 2021-06-21
  • 1 回答
  • 0 关注
  • 506 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信