7. src/runtime/runtime.go
// Select statement header.
// Known to compiler.
// Changes here must also be made in src/cmd/internal/gc/select.go's
selecttype.
type hselect struct {
tcase uint16 // total count of scase[]
ncase uint16 // currently filled scase[]
pollorder *uint16 // case poll order
lockorder *uint16 // channel lock order
scase [1]scase // one per case (in order of appearance)
}
// Select case descriptor.
// Known to compiler.
// Changes here must also be made in src/cmd/internal/gc/select.go's
selecttype.
type scase struct {
elem unsafe.Pointer // data element
c *hchan // chan
pc uintptr // return pc (for race detector /
msan)
13. 実験
package main
import "fmt"
func main() {
c := [65536]chan int{}
f := fmt.Println
select {
case i := <-c[0]:
f(i)
case i := <-c[1]:
f(i)
case i := <-c[2]:
f(i)
case i := <-c[3]:
f(i)
14. 実験
package main
import "fmt"
func main() {
c := [65536]chan int{}
f := fmt.Println
select {
case i := <-c[0]:
f(i)
case i := <-c[1]:
f(i)
case i := <-c[2]:
f(i)
case i := <-c[3]:
f(i)
case i := <-c[4]:
f(i)
case i := <-c[5]:
f(i)
case i := <-c[6]:
f(i)
case i := <-c[7]:
f(i)
15. 実験
package main
import "fmt"
func main() {
c := [65536]chan int{}
f := fmt.Println
select {
case i := <-c[0]:
f(i)
case i := <-c[1]:
f(i)
case i := <-c[2]:
f(i)
case i := <-c[3]:
f(i)
case i := <-c[4]:
f(i)
case i := <-c[5]:
f(i)
case i := <-c[6]:
f(i)
case i := <-c[7]:
f(i)
case i := <-c[8]:
f(i)
case i := <-c[9]:
f(i)
case i := <-c[10]:
f(i)
case i := <-c[11]:
f(i)
case i := <-c[12]:
f(i)
case i := <-c[13]:
f(i)
case i := <-c[14]:
f(i)
case i := <-c[15]:
f(i)
case i := <-c[16]:
f(i)
case i := <-c[17]:
16. 実験
package main
import "fmt"
func main() {
c := [65536]chan int{}
f := fmt.Println
select {
case i := <-c[0]:
f(i)
case i := <-c[1]:
f(i)
case i := <-c[2]:
f(i)
case i := <-c[3]:
f(i)
case i := <-c[4]:
f(i)
case i := <-c[5]:
f(i)
case i := <-c[6]:
f(i)
case i := <-c[7]:
f(i)
case i := <-c[8]:
f(i)
case i := <-c[9]:
f(i)
case i := <-c[10]:
f(i)
case i := <-c[11]:
f(i)
case i := <-c[12]:
f(i)
case i := <-c[13]:
f(i)
case i := <-c[14]:
f(i)
case i := <-c[15]:
f(i)
case i := <-c[16]:
f(i)
case i := <-c[17]:
f(i)
case i := <-c[18]:
f(i)
case i := <-c[19]:
f(i)
case i := <-c[20]:
f(i)
case i := <-c[21]:
f(i)
case i := <-c[22]:
f(i)
case i := <-c[23]:
f(i)
case i := <-c[24]:
f(i)
case i := <-c[25]:
f(i)
case i := <-c[26]:
f(i)
case i := <-c[27]:
f(i)
case i := <-c[28]:
f(i)
case i := <-c[29]:
f(i)
case i := <-c[30]:
f(i)
case i := <-c[31]:
f(i)
case i := <-c[32]:
f(i)
case i := <-c[33]:
f(i)
case i := <-c[34]:
f(i)
case i := <-c[35]:
f(i)
case i := <-c[36]:
f(i)
case i := <-c[37]:
f(i)
case i := <-c[38]:
f(i)
case i := <-c[39]:
f(i)
case i := <-c[40]:
f(i)
case i := <-c[41]:
f(i)
case i := <-c[42]:
f(i)
case i := <-c[43]:
f(i)
case i := <-c[44]:
f(i)
case i := <-c[45]:
f(i)
case i := <-c[46]:
f(i)
case i := <-c[47]:
f(i)
case i := <-c[48]:
f(i)
case i := <-c[49]:
f(i)
case i := <-c[50]:
f(i)
case i := <-c[51]:
f(i)
case i := <-c[52]:
f(i)
以下 65536 ま
で続く
20. reflect.Select
func main() {
cases := [65536]reflect.SelectCase{}
for i, _ := range cases {
cases[i] = reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(make(chan int)),
}
}
go func() {
for {
i := rand.Int() % len(cases)
cases[i].Chan.Send(reflect.ValueOf(i))
time.Sleep(time.Second)
}
}()
fmt.Println("ready")
for {
c, v, ok := reflect.Select(cases[:])
fmt.Println(c, v, ok)
}
}
リフレクションで select 相当の処理を書ける
21. 実行結果
ubuntu:gotorture:% go run uint16maxselect.go
ready
fatal error: selectrecv: too many cases
goroutine 1 [running]:
runtime.throw(0x521ce0, 0x1a)
...