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

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


发现系统调用 setrlimit 和 get 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 值保持不变。这个错误是由于我的内核有问题还是一个坏程序?我在哪里可以找到更多信息以及如何处理此类问题?


ABOUTYOU
浏览 514回答 1
1回答

郎朗坤

它按预期工作。setrlimit(2)。软限制是内核为相应资源强制执行的值。硬限制充当软限制的上限:非特权进程只能将其软限制设置为从 0 到硬限制范围内的值,并且(不可逆转地)降低其硬限制。特权进程(在 Linux 下:具有 CAP_SYS_RESOURCE 功能的进程)可以对任一限制值进行任意更改。rlimit.go: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)}输出:$ uname -aLinux 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 permittedRlimit 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 -aLinux peterSO 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:46:08 UTC 2013 i686 i686 i686 GNU/Linux$ go versiongo version devel +ba52f6399462 Thu Jul 25 09:56:06 2013 -0400 linux/386$ ulimit -Sn1024$ ulimit -Hn4096$ go build rlimit.go$ ./rlimit{1024 4096}Error Setting Rlimit  operation not permittedRlimit Final {1024 4096}$ sudo ./rlimit[sudo] password for peterSO: {1024 4096}Rlimit Final {999999 999999}$ 
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go