【发布时间】:2019-11-03 09:28:54
【问题描述】:
The Go Programming Language第8章对并发回显服务器有如下描述:
由 go 启动的函数的参数在 go 语句本身执行时被评估;因此 input.Text() 在主 goroutine 中被评估。
我不明白这一点。为什么 input.Text() 在主 goroutine 中被评估?它不应该在 go echo() goroutine 中吗?
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 224.
// Reverb2 is a TCP server that simulates an echo.
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
"time"
)
func echo(c net.Conn, shout string, delay time.Duration) {
fmt.Fprintln(c, "\t", strings.ToUpper(shout))
time.Sleep(delay)
fmt.Fprintln(c, "\t", shout)
time.Sleep(delay)
fmt.Fprintln(c, "\t", strings.ToLower(shout))
}
//!+
func handleConn(c net.Conn) {
input := bufio.NewScanner(c)
for input.Scan() {
go echo(c, input.Text(), 1*time.Second)
}
// NOTE: ignoring potential errors from input.Err()
c.Close()
}
//!-
func main() {
l, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Print(err) // e.g., connection aborted
continue
}
go handleConn(conn)
}
}
代码在这里:https://github.com/adonovan/gopl.io/blob/master/ch8/reverb2/reverb.go
【问题讨论】:
-
因为语言规范是这么说的。
-
所有参数在遇到
go关键字时进行评估,然后 goroutine 从这些计算值开始。如果你不想要这个,你需要启动一个func来计算这些值,像这样:go func() { yourFuncWithArgs(arg1.Text(), arg2) }();但是,这通常没有意义。同样的行为也适用于defer
标签: go concurrency goroutine