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

Geo*_*mas 8 operating-system network-programming system-calls go ulimit

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

找到systemcalls 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)
         }
Run Code Online (Sandbox Code Playgroud)

获得的输出是:

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 $ 
Run Code Online (Sandbox Code Playgroud)

所以我能够获得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
Run Code Online (Sandbox Code Playgroud)

pet*_*rSO 20

它按预期工作.

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)
}
Run Code Online (Sandbox Code Playgroud)

输出:

$ 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}
Run Code Online (Sandbox Code Playgroud)

更新:

我成功跑rlimit.golinux/amd64,你失败了linux/386.有一个Go错误GetrlimitSetrlimitLinux 32位发行版.这些错误已得到修复.

使用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}
$ 
Run Code Online (Sandbox Code Playgroud)