【问题标题】:How to set ulimit -n from a golang program?如何从 golang 程序中设置 ulimit -n?
【发布时间】:2013-07-22 22:29:08
【问题描述】:

我的目的是在 golang 程序中设置 ulimit -n,这样我就不必在全局范围内设置它,而是在程序中限制它。

找到系统调用 setrlimit 并获取相同的 rlimit。 (http://linux.die.net/man/2/setrlimit)

但是,当我尝试使用相同的示例程序时,我在设置值时收到错误提示无效参数。

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)
}

得到的输出是:

george@george-Not-Specified ~/work/odesk/progium/trial $ ./getRlimit 
{4294963002032703 0}
Error Setting Rlimit  invalid argument
Rlimit 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 -a
Linux george-Not-Specified 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linux
george@george-Not-Specified ~/work/odesk/progium/trial $ 

所以我能够得到 rlimit 设置限制失败并返回错误。 即使它失败了,当我再次取值时 MAX 值发生了变化,但 CUR 值保持不变。 这个错误可能是由于我的内核的一些问题还是它是一个坏程序?我在哪里可以找到更多信息以及如何处理此类问题?

更新:

修复后工作。

george@george-Not-Specified ~/work/odesk/progium/trial $ go build getRlimit.go 
george@george-Not-Specified ~/work/odesk/progium/trial $ ./getRlimit 
{1024 4096}
Error Setting Rlimit  operation not permitted
Rlimit Final {1024 4096}
george@george-Not-Specified ~/work/odesk/progium/trial $ sudo ./getRlimit                                                                                               
[sudo] password for george: 
{1024 4096}
Rlimit Final {999999 999999}
george@george-Not-Specified ~/work/odesk/progium/trial $ uname -a
Linux george-Not-Specified 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012    i686 i686 i686 GNU/Linux
george@george-Not-Specified ~/work/odesk/progium/trial $ go version
go version devel +7c42cfa28e24 Tue Jul 30 14:22:14 2013 +1000 linux/386

【问题讨论】:

    标签: network-programming operating-system go system-calls ulimit


    【解决方案1】:

    它按预期工作。

    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}
    

    更新:

    我为linux/amd64 成功运行rlimit.go,你为linux/386 失败。对于 Linux 32 位发行版,GetrlimitSetrlimit 中有一个 Go 错误。这些错误已得到修复。

    使用 Go default 分支 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}
    $ 
    

    【讨论】:

    • @GeorgeThomas 正如 PeterSO 所指出的:您是否以超级用户权限运行应用程序?
    • @GeorgeThomas:是的。您的uname 输出显示i686,我的输出显示x86_64。我必须设置一个 32 位的虚拟机才能完成调试。
    • 我也想知道 current 的值。 ulimit -n 返回 999999 但这是不同的。
    • @GeorgeThomas:这是一个 Go linux/386 错误。我正在修复。
    • @GeorgeThomas:查看我的更新答案。我已经修复了一些 linux/386 Go 错误。
    猜你喜欢
    • 2019-08-01
    • 2014-10-18
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2017-07-19
    • 2012-10-26
    • 2016-02-12
    • 2018-08-24
    相关资源
    最近更新 更多