Goããã°ã©ãã³ã°èšèªã®é·æã®1ã€ã¯ãTony Hoar
ã®Communicating Sequential Processesã®äœæ¥ã«åºã¥ãããçµã¿èŸŒã¿ã®äžŠè¡åŠçãµããŒãã§ãã Goã¯ããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®äŸ¿å©ãªäœæ¥ã®ããã«èšèšãããŠãããéåžžã«è€éãªäžŠè¡ããã°ã©ã ãéåžžã«ç°¡åã«æ§ç¯ã§ããŸãã ããããããŸããŸãªåæå®è¡ãã¿ãŒã³ãèŠèŠçã«ã©ã®ããã«èŠãããçåã«æã£ãããšã¯ãããŸãããïŒ
ãã¡ããã圌ãã¯èããŸããã äœããã®æ¹æ³ã§ãç§ãã¡ã¯çãèŠèŠçãªã€ã¡ãŒãžã§èããŸãã ã1ãã100ãã®æ°åãå«ããã®ã«ã€ããŠå°ãããšãé ã®äžã§äœããã®åœ¢ã§å³åº§ã«ãèŠãããŸãã ããšãã°ã1ãã100ãŸã§ã®ã·ãªãŒãºã¯ãæ°åãä»ããç·ãšããŠè¡šç€ºããã20床å³ã«90床å転ãã1000 +ãŸã§ç¶ããŸãã ãããŠãèšæ¶ãæãäžããŠãå£ã«æ²¿ã£ãããã«ãŒã«ãŒã ã®äžçªæåã®å¹Œçšåã§ãæ°åãæžãããŠããŠãæ°å20ãã¡ããã©è§ã«ãã£ãããšãæãåºããŸãã ããªãã¯ããããããªãèªèº«ã®ããã€ãã®ã¢ã€ãã¢ãæã£ãŠããŸãã ãŸãã¯ãå¥ã®ããããäŸ-äžå¹Žäžãšãã®å¹Žã®åå£ãæ³åããŠãã ãã-誰ããããããåè§ãšã¿ãªãããã®åé¢ã¯å£ç¯ã«å±ãã誰ãã¯åã«ãä»ã®èª°ãã«å±ããŸãã
ãšã«ãããGoãšWebGLã§åºæ¬çãªåæå®è¡ãã¿ãŒã³ãèŠèŠåããç§ã®è©Šã¿ã玹ä»ããŸãããã ãããã®ã€ã³ã¿ã©ã¯ãã£ããªèŠèŠåã¯ãå€ããå°ãªãããç§ã®é ã®äžã§ã®èŠæ¹ãåæ ããŠããŸãã ãããèªè
ã®èŠèŠåãšã©ãã»ã©éãããèãã®ã¯é¢çœãã§ãããã
ããã§ã¯ãæãåçŽãªäŸã§ãããããã«ã¡ã¯ã䞊è¡äžçãããå§ããŠãç§ã®ã¢ãããŒãã®æŠå¿µãç解ããŸãããã
ããã«ã¡ã¯ã³ã³ã«ã¬ã³ãã¯ãŒã«ã
package main func main() {
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ããã§éãç·ã¯ãŽã«ãŒãã³ãè¡šããæéã¯Y軞ããå®è¡ãããŸãããmainããšãgoïŒ19ããçµã¶çŽ°ãéãç·ã¯ãå
ç¥ãšåäŸã瀺ããŽã«ãŒãã³ã®ç掻ã®å§ãŸããšçµããã®å°ã§ãã èµ€ãç¢å°ã¯ããã£ãã«ã«ã¡ãã»ãŒãžãéä¿¡ããã€ãã³ãã瀺ããéä¿¡ãããå€ã¯çœ²åãããŠããŸãã å®éãããã£ãã«ãžã®éä¿¡ããšããã£ãã«ããã®èªã¿åããã¯2ã€ã®å¥åã®ã€ãã³ãã§ããããããã¡ãŒä»ããã£ãã«ãšãããã¡ãªããã£ãã«ã§ã¯åäœã倧ããç°ãªããŸãããããã2ã€ã®ã€ãã³ãã1ã€ãšããŠã¢ãã¡ãŒã·ã§ã³åããŸã-ããã£ãã«ãä»ããå€ã®éä¿¡ãã å¿åãŽã«ãŒãã³ã®ååã«ããæååãïŒ19ãã¯ãå®è¡äžã®ãŽã«ãŒãã³ã®å®éã®IDã§ãã Goroutine IDãå
¬åŒã«èªèããããšã¯ã§ããŸãããïŒèå¥åãéèŠãªåœ¹å²ãæããä»ã®åæå®è¡ã¢ãã«ãäœæããªãããã«ïŒããã®ãããªããã«ãŒã®ã±ãŒã¹ã«ã€ããŠã¯ãŸã å¯èœã§ã-ããã¯Scott Mansfield
ã®èšäº
ãGoroutine IDsãã«ããæžãããŠããŸãã
ã¿ã€ããŒ
å®éãäžèšã®æãåçŽãªHelloãworldã䜿çšããŠãåçŽãªã¿ã€ããŒãäœæã§ããŸãã Goæšæºã©ã€ãã©ãªã«ã¯time.Afterãtime.Tickãªã©ã®äŸ¿å©ãªé¢æ°ããããŸãããç¬èªã«å®è£
ããŠã¿ãŸããã-ãã£ã³ãã«ãäœæããgoroutinãéå§ããå¿
èŠãªæéã¹ãªãŒãããŠãã£ã³ãã«ã«æžã蟌ã¿ããã®ãã£ã³ãã«ãåŒã³åºãå
ã«è¿ãé¢æ°ãäœæããŸãã
package main import "time" func timer(d time.Duration) <-chan int { c := make(chan int) go func() { time.Sleep(d) c <- 1 }() return c } func main() { for i := 0; i < 24; i++ { c := timer(1 * time.Second) <-c } }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ããã§ãã ããããå
ã«é²ã¿ãŸãã
ãã³ãã³
ãã®èå³æ·±ã䞊è¡æ§ã®äŸã¯ãGoogleã®æåãªSameer Ajmani
Advanced Concurrency Patternsã¬ããŒãããåŒçšãããã®ã§ãã ãã¡ããããã®äŸã¯ããŸãé«åºŠã§ã¯ãããŸããããGoã®åæå®è¡ã«ç²ŸéããŠããã ãã®äººã«ãšã£ãŠã¯ãé¢çœããŠå®èšŒçã§ããã¯ãã§ãã
ãããã£ãŠãããŒãã«ã®åœ¹å²ãæããããŒãã«ãã£ãã«ããããintåå€æ°ã§ããããã®ã¹ãããŒã¯æ°ãæ ŒçŽããããŒã«ããŒã«ããããŸãããŸãããããŒãã«ããããŒã«ãââåãåºããïŒãã£ãã«ããèªã¿åãããïŒgorutinãã¬ãŒã€ãŒããããŸãã圌ãæã¡è² ããïŒå€æ°ãå¢ããïŒãã圌ãããŒãã«ã«æãæ»ããïŒãã£ã³ãã«ã«æžã蟌ãïŒã
package main import "time" func main() { var Ball int table := make(chan int) go player(table) go player(table) table <- Ball time.Sleep(1 * time.Second) <-table } func player(table chan int) { for { ball := <-table ball++ time.Sleep(100 * time.Millisecond) table <- ball } }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãã®æç¹ã§ãåã¢ãã¡ãŒã·ã§ã³ã§äœ¿çšå¯èœãª
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ã®ãªã³ã¯ã«ããäžåºŠæ³šæãåããããšæããŸã-æ°ããã¿ãã§éãããšã«ããããããã®3Dã¢ãã¡ãŒã·ã§ã³ã奜ããªããã«ç§»åãå転ãå¢å /æžå°ã衚瀺ãããã³æžéããããšãã§ããŸã/ã¹ããŒãã¢ããããŠåèµ·åããŸãã
ã§ã¯ã2ã€ã§ã¯ãªã3ã€ã®ãŽã«ãŒãã³ãå®è¡ããŸãããã
go player(table) go player(table) go player(table)
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãã®äŸã§ã¯ãåãã¬ã€ã€ãŒãé çªã«ããŒãã«ããããŒã«ãââåããŸãããããªãã¯çåã«æããããããŸãã-ãªãæ£ç¢ºã«ã誰ããã®é åºãä¿èšŒããŸããïŒ
ããã§ã®çãã¯ç°¡åã§ã-Goã©ã³ã¿ã€ã ã«ã¯ããã£ãã«ããèªã¿åãæºåãã§ããŠãããŽã«ãŒãã³çšã®
FIFOãã¥ãŒãå«ãŸããŠããããããã®é åºãéµå®ããŸãã ãã®å ŽåãåãŽã«ãŒãã³ã¯ããŒã«ãããŒãã«ã«éã£ãçŽåŸã«ãã¥ãŒã«å
¥ããŸãã ãã ãããã®åäœã¯å°æ¥å€æŽãããå¯èœæ§ãããã泚æã«é Œã䟡å€ã¯ãããŸããã ããããä»ã®ãšããã¯ããã§ããã3ã€ã§ã¯ãªã100ã®ãŽã«ãŒãã³ãèµ·åããŸãããã
for i := 0; i < 100; i++ { go player(table) }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯FIFOã®é åºãããæ確ã«ãªããŸãããã 100äžåã®ãŽã«ãŒãã³ãç°¡åã«èµ·åã§ããŸãïŒå®äŸ¡ã§ããã倧èŠæš¡ãªGoããã°ã©ã ã«æ°åäžåã®ãŽã«ãŒãã³ãå«ãŸããŠããŠãããŸããŸããïŒã ä»ã®ãã¿ãŒã³ã«ç§»ããŸãããã
ãã¡ã³ã€ã³
æãæåãªãã¿ãŒã³ã®1ã€ã¯ããããã
ãã¡ã³ã€ã³ãã¿ãŒã³ã§ãã ããã¯ãåŸã§èª¬æãã
ãã¡ã³ã¢ãŠããã¿ãŒã³ã®å察ã§ãã ã€ãŸãã
ãã¡ã³ã€ã³ã¯ãè€æ°ã®ãœãŒã¹ããèªã¿åãããã¹ãŠã1ã€ã®ãã£ãã«ã«å€éåããæ©èœã§ãã
äŸïŒ
package main import ( "fmt" "time" ) func producer(ch chan int, d time.Duration) { var i int for { ch <- i i++ time.Sleep(d) } } func reader(out chan int) { for x := range out { fmt.Println(x) } } func main() { ch := make(chan int) out := make(chan int) go producer(ch, 100*time.Millisecond) go producer(ch, 250*time.Millisecond) go reader(out) for i := range ch { out <- i } }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ã芧ã®ãšãããæåã®
ãããã¥ãŒãµãŒã¯100ããªç§ããšã«çªå·ãçæãã2çªç®ã®
ãããã¥ãŒãµãŒã¯250ããªç§ããšã«çªå·ãçæãã
ãªãŒããŒã¯äž¡æ¹ã®ãããã¥ãŒãµãŒããããã«çªå·ãåãåããŸãã å®éãå€éåã¯ã¡ã€ã³é¢æ°ã§çºçããŸãã
ãã¡ã³ã¢ãŠã
ãã¡ã³ã€ã³ã®å察ã¯ã
ãã¡ã³ã¢ãŠããŸãã¯
ã¯ãŒã«ãŒãã¿ãŒã³ã§ãã å€ãã®ãŽã«ãŒãã³ã¯1ã€ã®ãã£ãã«ããèªã¿åãããåŠçã®ããã«ããŒã¿ãååŸããŠãCPUã³ã¢éã§äœæ¥ãå¹æçã«åæ£ããŸãã ãããã£ãŠãååã¯ã
workers ãã§ãã Goã§ãã®ãã¿ãŒã³ãå®è£
ããã®ã¯éåžžã«ç°¡åã§ãããã£ã³ãã«ããã©ã¡ãŒã¿ãŒã«æž¡ããŠãŽã«ãŒãã³ã®ããã¯ãå®è¡ãããã®ãã£ã³ãã«ã«ããŒã¿ãæžã蟌ããšãGoã©ã³ã¿ã€ã ã®ãããã§å€éåãšé
ä¿¡ãèªåçã«è¡ãããŸãã
package main import ( "fmt" "sync" "time" ) func worker(tasksCh <-chan int, wg *sync.WaitGroup) { defer wg.Done() for { task, ok := <-tasksCh if !ok { return } d := time.Duration(task) * time.Millisecond time.Sleep(d) fmt.Println("processing task", task) } } func pool(wg *sync.WaitGroup, workers, tasks int) { tasksCh := make(chan int) for i := 0; i < workers; i++ { go worker(tasksCh, wg) } for i := 0; i < tasks; i++ { tasksCh <- i } close(tasksCh) } func main() { var wg sync.WaitGroup wg.Add(36) go pool(&wg, 36, 50) wg.Wait() }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ããã§æ³šç®ãããããšã®1ã€ã¯ã䞊è¡æ§ã§ãã gorutins-workersã䞊è¡ããŠå®è¡ããããã£ã³ãã«ã次ã
ãšãäœæ¥ãããŠããããšã«æ°ä»ãã®ã¯ç°¡åã§ãã ãã®ã¢ãã¡ãŒã·ã§ã³ããããŽã«ãŒãã³ããããã»ãŒåæã«è¡ãããšãããããŸãã æ®å¿µãªããããããŸã§ã®ãšããããŽã«ãŒãã³ãå®éã«æ©èœãããããã¯ãããŠããã¢ãã¡ãŒã·ã§ã³ã«ã¯è¡šç€ºãããŠããŸããããŸããããã§ã¯ã¿ã€ã ã¹ã±ãŒã«ã¯ãã§ã«ãšã©ãŒãšã©ãŒã®ãããå€ã«è¿ããªã£ãŠããŸãããå
·äœçã«ã¯ããã®ã¢ãã¡ãŒã·ã§ã³ã¯4ã³ã¢ã§å®è¡ãããŠããããã°ã©ã ãã€ãŸãGOMAXPROCS = 4 ã ãã®åé¡ã«ã€ããŠããå°ã詳ããæ€èšããŸãã
ãããŸã§ã®éããã£ãšè€éãªãã®ãè©ŠããŠã¿ãŸããã-ç¬èªã®ãµãã¯ãŒã«ãŒãæã€ã¯ãŒã«ãŒã
package main import ( "fmt" "sync" "time" ) const ( WORKERS = 5 SUBWORKERS = 3 TASKS = 20 SUBTASKS = 10 ) func subworker(subtasks chan int) { for { task, ok := <-subtasks if !ok { return } time.Sleep(time.Duration(task) * time.Millisecond) fmt.Println(task) } } func worker(tasks <-chan int, wg *sync.WaitGroup) { defer wg.Done() for { task, ok := <-tasks if !ok { return } subtasks := make(chan int) for i := 0; i < SUBWORKERS; i++ { go subworker(subtasks) } for i := 0; i < SUBTASKS; i++ { task1 := task * i subtasks <- task1 } close(subtasks) } } func main() { var wg sync.WaitGroup wg.Add(WORKERS) tasks := make(chan int) for i := 0; i < WORKERS; i++ { go worker(tasks, &wg) } for i := 0; i < TASKS; i++ { tasks <- i } close(tasks) wg.Wait() }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãã ãã¡ãããããå€ãã®äœæ¥è
ãšãµãã¯ãŒã«ãŒãå®è¡ããããšãã§ããŸããããã¢ãã¡ãŒã·ã§ã³ãã§ããã ãæ確ã«ããããã«ããŸããã
ã¯ããã«è€éãªãã¿ãŒã³ããµãã¯ãŒã«ãŒãšãµãã¯ãŒã«ãŒãããã³ããèªäœããã£ãã«ãä»ããŠéä¿¡ããããã£ãã«ããããŸããããã¡ã³ã¢ãŠãã®ã¢ã€ãã¢ã¯æ確ã§ããå¿
èŠããããŸãã
ãµãŒããŒ
次ã®äžè¬çãªãã¡ã³ã¢ãŠããã¿ãŒã³ã¯ã
serversã§ãã ããã¯ããŽã«ãŒãã³ãåçã«éå§ããå¿
èŠãªäœæ¥ãå®è¡ããå®äºãããšããäºå®ã«ãã£ãŠåºå¥ãããŸãã ãããŠããã®ãã¿ãŒã³ã¯ãµãŒããŒã®å®è£
ã«ãã䜿çšãããŸã-ããŒãããªãã¹ã³ããæ¥ç¶ãåãå
¥ããgoroutineãéå§ããŸãããŽã«ãŒãã³ã¯çä¿¡èŠæ±ãåŠçããæ¥ç¶ãããã«æž¡ããŸãããã®æç¹ã§ããã«ãªãã¹ã³ãã次ã®æ¥ç¶ãåŸ
ã¡ãŸãã ããã¯éåžžã«äŸ¿å©ã§ã10Kæ¥ç¶ã«èããéåžžã«ã·ã³ãã«ãªå¹ççãªãµãŒããŒãå®è£
ã§ããŸãã 次ã®äŸãèŠãŠãã ããã
package main import "net" func handler(c net.Conn) { c.Write([]byte("ok")) c.Close() } func main() { l, err := net.Listen("tcp", ":5000") if err != nil { panic(err) } for { c, err := l.Accept() if err != nil { continue } go handler(c) } }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãã®äŸã¯ããŸãèå³æ·±ããã®ã§ã¯ãããŸãããå®éãããã§ã¯å®éã«äœãèµ·ãããŸããã ãã¡ãããå
éšã«ã¯å·šå€§ãªè€éããšã¢ã«ãŽãªãºã ãæ
éã«é ãããŠããŸãã
ãã·ã³ãã«ãã¯è€éã§ããããããããµãŒããŒã«ã¢ã¯ãã£ããã£ãè¿œå ããŠã¿ãŸããããããšãã°ãåãŽã«ãŒãã³ãã¯ã©ã€ã¢ã³ãã®ã¢ãã¬ã¹ãæžã蟌ããã¬ãŒãè¿œå ããŸãã
package main import ( "fmt" "net" "time" ) func handler(c net.Conn, ch chan string) { ch <- c.RemoteAddr().String() c.Write([]byte("ok")) c.Close() } func logger(ch chan string) { for { fmt.Println(<-ch) } } func server(l net.Listener, ch chan string) { for { c, err := l.Accept() if err != nil { continue } go handler(c, ch) } } func main() { l, err := net.Listen("tcp", ":5000") if err != nil { panic(err) } ch := make(chan string) go logger(ch) go server(l, ch) time.Sleep(10 * time.Second) }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯å®èšŒçã«ååã§ããïŒ ãã®ã¢ãã¡ãŒã·ã§ã³ã¯ãæ¥ç¶ã®æ°ãå¢ãããã¬ãŒãããŸãéããªãå Žåããã¬ãŒãããã«ããã«ããã¯ã«ãªãå¯èœæ§ãããããšã瀺ããŠããŸãïŒããšãã°ãããŒã¿ãã·ãªã¢ã«åããŠä»ã®å Žæã«éä¿¡ããŸãïŒã ãããããã§ã«ããã£ãŠãã
ãã¡ã³ã¢ãŠããã¿ãŒã³ã䜿çšããããšã§ããã解決ã§ããŸãã æžããŸãããã
ãµãŒããŒ+ã¯ãŒã«ãŒ
ã¯ãŒã«ãŒãåãããµãŒããŒã®äŸã¯ãçºè¡šãããã°ããã®ãœãªã¥ãŒã·ã§ã³ã®ãããã«é«åºŠãªããŒãžã§ã³ã§ãã 圌ã¯ãããã€ãã®ãŽã«ãŒãã³ã§ãã¬ãŒãéå§ããã ãã§ãªããçµæïŒããšãã°ããªã¢ãŒããµãŒãã¹ãžã®èšé²ã®çµæïŒã䜿çšããŠãã¬ãŒããããŒã¿ãåéããŸãã
ã³ãŒããšã¢ãã¡ãŒã·ã§ã³ãèŠãŠã¿ãŸãããã
package main import ( "net" "time" ) func handler(c net.Conn, ch chan string) { addr := c.RemoteAddr().String() ch <- addr time.Sleep(100 * time.Millisecond) c.Write([]byte("ok")) c.Close() } func logger(wch chan int, results chan int) { for { data := <-wch data++ results <- data } } func parse(results chan int) { for { <-results } } func pool(ch chan string, n int) { wch := make(chan int) results := make(chan int) for i := 0; i < n; i++ { go logger(wch, results) } go parse(results) for { addr := <-ch l := len(addr) wch <- l } } func server(l net.Listener, ch chan string) { for { c, err := l.Accept() if err != nil { continue } go handler(c, ch) } } func main() { l, err := net.Listen("tcp", ":5000") if err != nil { panic(err) } ch := make(chan string) go pool(ch, 4) go server(l, ch) time.Sleep(10 * time.Second) }
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãã¬ãŒã®ã¿ã¹ã¯ã4ã€ã®ãŽã«ãŒãã³éã§å¹æçã«åæ£ããããšã§ãµãŒããŒãæ¹åããŸãããããã¬ãŒãããã«ããã¯ã«ãªãå¯èœæ§ãããããšãããããŸããã æ°åã®æ¥ç¶ã1ã€ã®ãã£ãã«ã«åæããŸãã ãŽã«ãŒãã³éã§å€éåããåã ãããããã¡ãããããã¯ä»¥åã®ããŒãžã§ã³ãããã¯ããã«å€§ããªè² è·ã§æ¢ã«èµ·ãããŸãã
ãšã©ãã¹ããã¹ã®ãµãã
ããããããªããã¡ã³ã€ã³/ãã¡ã³ã¢ãŠãã®å®éšã ããèå³æ·±ãäŸãèŠãŠã¿ãŸãããã ç§ã®ãæ°ã«å
¥ãã®1ã€ã¯ãã¬ããŒãã
Go Concurrency Patterns ãã«ãããŽã«ãŒãã³ãšãã£ãã«ã®ãSieve of Eratosthenesãã§ãã ãšã©ãã¹ããã¹ã®ãµããã¯ãäžããããéçãŸã§çŽ æ°ãèŠã€ããããã®å€ä»£ã®ã¢ã«ãŽãªãºã ã§ãã ãã®æ¬è³ªã¯ãèŠã€ãã£ãåŸç¶ã®åçŽ æ°ã§å²ãåãããã¹ãŠã®æ°ãé çªã«ã¹ãã©ã€ã¯ããããšã«ãããŸãã é¡ã¢ã«ãŽãªãºã ã¯ãç¹ã«ãã«ãã³ã¢ãã·ã³ã§ã¯ããŸãå¹ççã§ã¯ãããŸããã
ãŽã«ãŒãã³ãšãã£ãã«ã䜿çšãããã®ã¢ã«ãŽãªãºã ã®å®è£
ãªãã·ã§ã³ã¯ãèŠã€ãã£ãçŽ æ°ããšã«1ã€ã®ãŽã«ãŒãã³ãå®è¡ãããã®ãŽã«ãŒãã³ã¯ããã§é€ç®ãããæ°ããã£ã«ã¿ãªã³ã°ããŸãã ãŽã«ãŒãã³ã®æåã®çŽ æ°ãèŠã€ãããšãã¡ã€ã³ã®ãŽã«ãŒãã³ïŒã¡ã€ã³ïŒã«éä¿¡ãããç»é¢ã«è¡šç€ºãããŸãã ãŸãããã®ã¢ã«ãŽãªãºã ã¯æãå¹ççã§ã¯ãããŸããããé©ãã»ã©ãšã¬ã¬ã³ãã§ãã ã³ãŒãèªäœã¯æ¬¡ã®ãšããã§ãã
ã¢ãã¡ãŒã·ã§ã³ãèŠãŠã¿ãŸãããã
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯äžèšã®ãªã³ã¯ã®3D空éã§ã€ã³ã¿ã©ã¯ãã£ãã«ãããããšãå¿ããªãã§ãã ããã ç§ã¯ãã®äŸãããã«å®äŸã§ããããæ¬åœã«å¥œãã§ã3Dã§ãããç 究ããããšã¯ã¢ã«ãŽãªãºã èªäœãããããç解ããã®ãå©ããããšãã§ããŸãã æåã®goroutineïŒ
generate ïŒãæåã®çŽ æ°ïŒ2ïŒã
mainã«éä¿¡ããæåã®goroutineãã£ã«ã¿ãŒãéå§ããã2ã3ã5ã7ããµããã«ãããŸã...ãããŠãèŠã€ãã£ãæ°ããçŽ æ°ã
mainã«éä¿¡ããããã³ã«-ããã¯ç¹ã«è¯ãã§ãäžé¢å³ããèŠãã 3Dãå«ãçŸããã¢ã«ãŽãªãºã ã
GOMAXPROCS
ã¯ãŒã«ãŒã®äŸã«æ»ããŸãããã ãã®äŸãGOMAXPROCS = 4ã§å®è¡ããããšãèŠããŠããŸããïŒ ããã¯ãããããã¹ãŠã®ã¢ãã¡ãŒã·ã§ã³ãæãããŠããããã§ã¯ãªããããããå®éã®ããã°ã©ã ã®æ¬åœã®çè·¡ã ããã§ãã
ã¯ããã«ãèšæ¶ãæŽæ°ããŠ
GOMAXPROCSãæãåºããŸãããã
GOMAXPROCSã¯ãã³ãŒããåæã«å®è¡ã§ããCPUã³ã¢ã®æ倧æ°ãèšå®ããŸã
å®éã®äœæ¥ãè¡ãããã«ãã¯ãŒã«ãŒã®ã³ãŒããå°ãå€æŽããŸããã ããã»ããµãããŒãããã ãã§ãªããã¹ãªãŒãããŸãã 次ã«ããããã12ã³ã¢ã®2ã€ã®ããã»ããµãŒãæèŒããLinuxãã·ã³ã§ãå€æŽãªãã§ã³ãŒããå®è¡ããŸãã-æåã«GOMAXPROCS = 1ã§ã次ã«GOMAXPROCS = 24ã§ã
ã ããã æåã®ã¢ãã¡ãŒã·ã§ã³ã§ã¯ãåãããã°ã©ã ã1çªç®ã®ã³ã¢ã§å®è¡ããã2çªç®ã®ã¢ãã¡ãŒã·ã§ã³ã§ã¯24ã³ã¢ã§å®è¡ãããŠããŸãã
WebGLã¢ãã¡ãŒã·ã§ã³1 WebGLã¢ãã¡ãŒã·ã§ã³24ãããã®äŸã§ã¯ãæéã®ã¢ãã¡ãŒã·ã§ã³ã®é床ã¯ç°ãªããŸããïŒãã¹ãŠã®ã¢ãã¡ãŒã·ã§ã³ã®é«ããäžå®ã®æéãããããã«ãããã£ãïŒãéãã¯æããã§ãã GOMAXPROCS = 1ã®å Žåã次ã®ã¯ãŒã«ãŒã¯ãããã»ããµã³ã¢ã解æŸãããåã®ãŽã«ãŒãã³ããã®éšåã解決ãããšãã«ã®ã¿ãžã§ããåãåããŸãïŒãã£ãã«ããèªã¿åããŸãïŒã 24åã®ã³ã¢ã«ããããŽã«ãŒãã³ã¯ã»ãšãã©ããã«ã¿ã¹ã¯ã解æããé«éåãå®çŸããŸãã
ãã ããGOMAXPROCSã®å¢å ãåžžã«çç£æ§ã®åäžã«ã€ãªãããšã¯éãããã³ã¢æ°ã®å¢å ã«ãã£ãŠäœäžããããšããããããšãç解ããããšãéèŠã§ãã
ãŽã«ãŒãã³ã®ãªãŒã¯
䞊è¡æ§ã®äžçããä»ã«äœãå®èšŒã§ããŸããïŒ ç§ã®é ã«æµ®ãã¶ãã®ã®äžã€ã¯ããŽã«ãŒãã³ã®ãªãŒã¯ã§ãã é倱ã«ãã£ãŠçºçããå¯èœæ§
ããããŸã ã
ããšãã°ããŽã«ãŒãã³ã
èµ·åããããç¯å²å€ã«ãªã£ãå Žåãªã©ã§ãã
åããŠã®ïŒãããŠå¯äžã®ïŒãŽã«ãŒãã³ãªãŒã¯ã«ééããæãããåçãé ã«
æµ®ãã³ ãæåéãã次ã®é±æ«ã«è¿
éãªç£èŠã®ããã«
expvarmonãæžã
ãŸãã ã ãããŠä»ããã®æãããåçãWebGLã§èŠèŠåã§ããŸãã
ã芧ãã ããïŒ
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ãããèŠãããšããçãã§ã:)åè¡ã¯ããªãã®ããã°ã©ã ã®ããã«è²»ããããã³ã³ãã¥ãŒã¿ãŒè³æºãšæéç匟ã§ãã
䞊è¡æ§ã¯äžŠåæ§ã§ã¯ãããŸãã
䞊è¡æ§ãšããèšèã¯ãã°ãã°ã䞊è¡æ§ããšèš³ãããŸãããããã¯å®å
šã«çå®ã§ã¯ãããŸããã å®ã®ãšãããç§ã¯è¯ã翻蚳ãç¥ããŸãããã ããã翻蚳ãªãã§ã©ãã«ã§ãæžããŸãã ãããã䞊è¡æ§ãšäžŠè¡æ§ã®éãã説æãããããã¯èªäœã¯ãããã»ãã€ã¯ã«ããçŽ æŽããã
åãå ããå ±åæžãå«ãã
äœåºŠã å
¬éãã ãŠããŸãã ãŸã èŠãŠããªããªãèŠãŠãã ããã
èŠããã«ïŒ
䞊è¡æ§ã¯ã䞊è¡ããŠå®è¡ãããå€ãã®ããšã§ãã
䞊è¡æ§ã¯ãããã°ã©ã ãæ§æããæ¹æ³ã§ãã
ãããã®æŠå¿µã¯å€å°çŽäº€ããŠããããšãç解ããããšãéèŠã§ã-䞊è¡ããã°ã©ã ã¯äžŠåã§ããå Žåãšããã§ãªãå ŽåããããŸãã ç°ãªãGOMAXPROCSã䜿çšãããã®äŸãããå°ãèŠãŸãããåãã³ãŒãã1çªç®ã®ã³ã¢ïŒé£ç¶ïŒãš24çªç®ã®ã«ãŒãã«ïŒäžŠåïŒã®äž¡æ¹ã§å®è¡ãããŸããã
äžèšã®ãªã³ã¯ãšã¬ããŒãããå€ãã®ä»®å®ãç¹°ãè¿ãããšãã§ããŸãããããã¯ãã§ã«ç§ã®åã§è¡ãããŠããŸãã èŠèŠçã«è¡šç€ºããããã«ããŠãã ããã
ããã䞊è¡æ§ã§ãã å€ãã®ããšã䞊è¡ããŠå®è¡ãããŠããŸãã
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ããã䞊ååŠçã§ãã ããã«å€ãã®äžŠåéšåããã ããäœãå€ãããŸããã
ã€ã³ã¿ã©ã¯ãã£ããªWebGLãã¢ãžã®ãªã³ã¯ããããããã«ãããŸã-䞊è¡æ§ïŒ
ãããŠãããã«ãããŸãïŒ
ãããŠãããã䞊è¡æ§ã§ãã
ããã¯ã©ã®ããã«è¡ãããŸãããïŒ
ãããã®ã¢ãã¡ãŒã·ã§ã³ãäœæããããã«ã
gotracerãš
gothree.jsã® 2ã€ã®ããã°ã©ã ãäœæã
ãŸãã ã æåã®ãã®ã¯æ¬¡ã®ããšãè¡ããŸãïŒ
- Goã®äŸã®ãœãŒã¹ã³ãŒãã®ASTããªãŒã解æãïŒGoã®åçŽãªææ³ã®ãã1ã€ïŒãåæå®è¡æ§ã«é¢é£ããã€ãã³ãã«ç¹å¥ãªåºåãæ¿å
¥ããŸãããŽã«ãŒãã³ã®éå§/åæ¢ããã£ãã«ãžã®æžã蟌ã¿/èªã¿åãããã£ãã«ã®äœæ
- å€æŽãããããã°ã©ã ãèµ·åããŸã
- åºåã解æããã€ãã³ããšã¿ã€ã ã¹ã¿ã³ããæã€ç¹å¥ãªJSONãçæããŸã
çµæã®JSONã®äŸïŒ
次ã«ã
gothree.jsã¯è±ªè¯ãª
Three.jsã©ã€ãã©ãªã®ãã¯ãŒã䜿çšããŠãWebGLã䜿çšããŠãã®ããŒã¿ã3Dã§æç»ããã³ã¢ãã¡ãŒã·ã§ã³åããŸãã ããã1ã€ã®ãã¢ããŒãžã«å§çž®ããå°ããªã©ãããŒã§å®äºã§ãã
ãã ãããã®ã¢ãããŒãã¯éåžžã«éãããŠããŸãã æ£ãããã¬ãŒã¹ãååŸããã«ã¯ããµã³ãã«ãéåžžã«æ
éã«éžæãããã£ãã«ã®ååãå€æŽããå¿
èŠããããŸããã ãã®ã¢ãããŒãã§ã¯ãé¢æ°å
ã§ç°ãªãæ¹æ³ã§åŒã³åºãããå ŽåããŽã«ãŒãã³éã§ãã£ãã«ãæ¥ç¶ããç°¡åãªæ¹æ³ã¯ãããŸããã ã¿ã€ãã³ã°ã«ãåé¡ããããŸã-ã³ã³ãœãŒã«ãžã®åºåã«ã¯ããŽã«ãŒãã³ã®èµ·åããã£ã³ãã«ãžã®æžã蟌ã¿ãçµäºãããæéããããããšããããããããã€ãã®äŸã§ã¯ãæéãæ¿å
¥ããããšã§å°ãåŒãç· ãŸããªããã°ãªããŸããã§ããïŒã¹ãªãŒãã®äŸã§ã¯ãã¢ãã¡ãŒã·ã§ã³ãå°ãééã£ãŠããŸãïŒã
Vobschemäœãã ãããç§ããŸã ã³ãŒããéããªãäž»ãªçç±ã§ãã ä»
ã Dmitry Vyukovã®
å®è¡ãã¬ãŒãµãŒã§éãã§ããŸã-ãã£ã³ãã«ã«éä¿¡ããããã®ã«é¢ããæ
å ±ã¯å«ãŸããŠããŸããããæãŸããã¬ãã«ã®è©³çŽ°ãæäŸããŠããããã§ãã ãããããæã詳现ãªãã¬ã€ã«ãéæããããã®ããã€ãã®ä»ã®æ¹æ³ãããã§ããããç§ã¯ããã«æ¢æ±ããŸãã ã¢ã€ãã¢ãããå Žåã¯ãTwitterãŸãã¯ã³ã¡ã³ãã§ã¡ãŒã«ããŠãã ããã ãã®ããŒã«ãæçµçã«ãäŸå€ãªããã¹ãŠã®Goããã°ã©ã ã«é©çšå¯èœãª3Dåæå®è¡ãããã¬ãŒã«æé·ããã®ã¯çŽ æŽãããããšã§ãã
ãã®èšäºã¯å
ã
ã
ãªãŽã£ãŠã®
Go MeetupïŒ2016幎1æ23æ¥ïŒ ã§ã®ã¬ããŒãã®
圢åŒã§ãã ããç§ã®ããã°ã§è±èªã§å
¬éãããŸãã ã
HackerNewsãš
Redditã§ã ã