7

필자는 golang 프로그램에서 ulimit -n을 설정하여 전역으로 설정하지 않고 프로그램 내에서 제한 할 수 있도록했습니다.golang 프로그램에서 ulimit -n을 설정하는 방법은 무엇입니까?

발견 된 시스템 호출 setrlimit과 get rlimit가 동일합니다. (http://linux.die.net/man/2/setrlimit)

그러나 같은 샘플 프로그램을 시도 할 때 값을 설정하는 동안 잘못된 인수를 말하는 오류가 발생했습니다.

[email protected] ~/work/odesk/progium/trial $ ./getRlimit 
{4294963002032703 0} 
Error Setting Rlimit invalid argument 
Rlimit Final {4294963002032703 999999} 
[email protected] ~/work/odesk/progium/trial $ sudo ./getRlimit 
[sudo] password for george: 
{4294963002032703 0} 
Error Setting Rlimit invalid argument 
Rlimit Final {4294963002032703 999999} 
[email protected] ~/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 
[email protected] ~/work/odesk/progium/trial $ 

그래서 나는 rlimit 실패 한계를 설정을 얻을 수 있었고, 오류를 반환했습니다 : 얻을

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

출력했다. 값을 다시 가져 왔을 때 MAX 값이 변경되었지만 CUR 값은 그대로 유지됩니다. 이 오류는 내 커널에 문제가 있거나 나쁜 프로그램 일 수 있습니까? 더 많은 정보를 얻고이를 어떻게 처리 할 수 ​​있습니까?

업데이트 : 수정이 이루어진

작품 후.

[email protected] ~/work/odesk/progium/trial $ go build getRlimit.go 
[email protected] ~/work/odesk/progium/trial $ ./getRlimit 
{1024 4096} 
Error Setting Rlimit operation not permitted 
Rlimit Final {1024 4096} 
[email protected] ~/work/odesk/progium/trial $ sudo ./getRlimit                        
[sudo] password for george: 
{1024 4096} 
Rlimit Final {999999 999999} 
[email protected] ~/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 
[email protected] ~/work/odesk/progium/trial $ go version 
go version devel +7c42cfa28e24 Tue Jul 30 14:22:14 2013 +1000 linux/386 

답변

14

예상대로 작동합니다.

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} 

UPDATE : 나는 성공적으로 linux/amd64에 대한 rlimit.go을 실행

, 당신은 linux/386 실패했습니다. Linux 용 32 비트 배포판의 경우 Go 버그가 GetrlimitSetrlimit입니다. 이 버그가 수정되었습니다.

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} 
$ 
+0

내 경우에 작동하지 않는 이유가 있습니까? –

+0

@GeorgeThomas PeterSO가 지적했듯이 : 수퍼 유저 권한으로 애플리케이션을 실행하고 있습니까? – elithrar

+0

두 가지 방법을 시도했지만 여전히 동일했습니다. –