标签:fun 开始 bsp efi package %s test \n []
1.code example
公共方法
func testDomain(ii string) {
time.Sleep(time.Second * 4)
fmt.Printf("pid: %d___point addr: %d___%s \n", GoID(), &ii, ii)
}
func GoID() int {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}
2. 错误示范
var a []string
for i := 1; i < 5; i++ {
a = append(a, fmt.Sprintf("%d", i))
}
for _, i := range a {
fmt.Printf("-----%s---\n", i)
go func() {
time.Sleep(time.Second * 4)
testDomain(i)
}()
}
打印发现i每次地址都是同一个
协助每次先阻塞4秒
4秒后 i的值是4, 这是协程中的方法testDomain开始工作,将i的值传给自己的形参
3. 正确示范
for _, i := range a {
fmt.Printf("-----%s---\n", i)
go func(a string) {
//time.Sleep(time.Second * 4)
testDomain(a)
}(i)
}
这种操作会先将i的值传递给形参a,i的变化不会对testDomain方法的执行产生影响
4. 完整代码
package main
import (
"fmt"
"runtime"
"strconv"
"strings"
"time"
)
func main() {
var a []string
for i := 1; i < 5; i++ {
a = append(a, fmt.Sprintf("%d", i))
}
for _, i := range a {
fmt.Printf("-----%s---\n", i)
go func(a string) {
//time.Sleep(time.Second * 4)
testDomain(a)
}(i)
go func() {
time.Sleep(time.Second * 4)
testDomain(i)
}()
fmt.Println(&i)
time.Sleep(time.Second * 1)
}
time.Sleep(100 * time.Second)
}
func testDomain(ii string) {
time.Sleep(time.Second * 4)
fmt.Printf("pid: %d___point addr: %d___%s \n", GoID(), &ii, ii)
}
func GoID() int {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}
golang range for循环中如何正确的给goroutine传参
标签:fun 开始 bsp efi package %s test \n []
原文地址:https://www.cnblogs.com/waken-captain/p/10496454.html