众所周知,golang低版本需要自己手动设置cpu核数,才能保证并发的执行
packagemain
import(
"errors"
"fmt"
"runtime"
"strconv"
"strings"
"testing"
)
funcmain(){
t:=&testing.T{}
TestSetcpu(t)
}
funcTestSetcpu(t*testing.T){
currentcpu:=runtime.GOMAXPROCS(-1)
maxcpu:=runtime.Numcpu()
halfcpu:=int(0.5*float32(maxcpu))
ifhalfcpu<1{
halfcpu=1
}
fori,test:=range[]struct{
inputstring
outputint
shouldErrbool
}{
{"1",1,false},{"-1",currentcpu,true},{"0",{"100%",maxcpu,{"50%",halfcpu,{"110%",{"-10%",{"invalidinput",{"invalidinput%",{"9999",//overavailablecpu
}{
err:=setcpu(test.input)
iftest.shouldErr&&err==nil{
fmt.Printf("Test%d:Expectederror,buttherewasn'tany",i)
}
if!test.shouldErr&&err!=nil{
fmt.Printf("Test%d:Expectednoerror,buttherewasone:%v",i,err)
}
ifactual,expected:=runtime.GOMAXPROCS(-1),test.output;actual!=expected{
fmt.Printf("Test%d:GOMAXPROCSwas%dbutexpected%d",actual,expected)
}else{
fmt.Printf("--%v%v\n",expected)
}
//teardown
runtime.GOMAXPROCS(currentcpu)
}
}
funcsetcpu(cpustring)error{
varnumcpuint
availcpu:=runtime.Numcpu()
ifstrings.HasSuffix(cpu,"%"){
//Percent
varpercentfloat32
pctStr:=cpu[:len(cpu)-1]
pctInt,err:=strconv.Atoi(pctStr)
iferr!=nil||pctInt<1||pctInt>100{
returnerrors.New("invalidcpuvalue:percentagemustbebetween1-100")
}
percent=float32(pctInt)/100
numcpu=int(float32(availcpu)*percent)
}else{
//Number
num,err:=strconv.Atoi(cpu)
iferr!=nil||num<1{
returnerrors.New("invalidcpuvalue:provideanumberorpercentgreaterthan0")
}
numcpu=num
}
ifnumcpu>availcpu{
numcpu=availcpu
}
runtime.GOMAXPROCS(numcpu)
returnnil
}
关于golang的GOMAXPROCS的申明:
// GOMAXPROCS sets the maximum number of cpus that can be executing
// simultaneously and returns the prevIoUs setting. If n < 1,it does not
// change the current setting.
// The number of logical cpus on the local machine can be queried with Numcpu.
// This call will go away when the scheduler improves.