不去例行公事,频道按通话顺序工作吗?
Doesn't go routine and the channels work in order of call?
不按常规进行,频道按调用顺序工作。
并在区域变量之间进行常规共享值?
main.go
var dataSendChannel = make(chan int)
func main() {
a(dataSendChannel)
time.Sleep(time.Second * 10)
}
func a(c chan<- int) {
for i := 0; i < 1000; i++ {
go b(dataSendChannel)
c <- i
}
}
func b(c <-chan int) {
val := <-c
fmt.Println(val)
}
输出
> go run main.go
0
1
54
3
61
5
6
7
8
9
频道 已排序。 Goroutines 不是。只要逻辑上 允许 到 运行,Goroutine 可能会 运行 或停止,或多或少是随机的。他们 必须 在您强迫他们这样做时停止并等待,例如,通过尝试在完整通道上写入,或对已锁定的互斥体使用 mutex.Lock()
调用,或任何此类事情。
您的 dataSendChannel
是无缓冲的,因此写入它的尝试将暂停,直到某个 goroutine 主动尝试从中读取。函数 a
派生出一个 goroutine,该 goroutine 将尝试读取一次 (go b(...)
),然后写入并因此等待至少一个 reader 读取。函数b
立即开始读取,等待数据。这解除了函数 a
的阻塞,它现在可以写入一些整数值。函数 a
现在可以衍生出另一个 b
的实例,它开始读取;这可能发生在获得值的 b
开始调用 fmt.Println
之前、期间或之后。 b
的第二个实例现在必须等待某人——在本例中是 always 函数 a
,运行 循环——发送另一个值,但 a
会尽快执行此操作。 b
的第二个实例现在可以开始调用 fmt.Println
,但它可能(主要是随机的)还没有机会这样做。 b
的第一个实例可能已经在 fmt.Println
中,或者可能还没有,第二个实例可能 运行 第一个——或者可能 both 稍等片刻,b
的 第三个 实例启动,从通道中读取一些值,依此类推。
无法保证 b
的哪个 实例实际进入 fmt.Println
,因此您的值看到印刷品将以某种半随机顺序出现。如果您希望各种 b
实例自行排序,它们将需要以某种方式执行此操作。
不按常规进行,频道按调用顺序工作。
并在区域变量之间进行常规共享值?
main.go
var dataSendChannel = make(chan int)
func main() {
a(dataSendChannel)
time.Sleep(time.Second * 10)
}
func a(c chan<- int) {
for i := 0; i < 1000; i++ {
go b(dataSendChannel)
c <- i
}
}
func b(c <-chan int) {
val := <-c
fmt.Println(val)
}
输出
> go run main.go
0
1
54
3
61
5
6
7
8
9
频道 已排序。 Goroutines 不是。只要逻辑上 允许 到 运行,Goroutine 可能会 运行 或停止,或多或少是随机的。他们 必须 在您强迫他们这样做时停止并等待,例如,通过尝试在完整通道上写入,或对已锁定的互斥体使用 mutex.Lock()
调用,或任何此类事情。
您的 dataSendChannel
是无缓冲的,因此写入它的尝试将暂停,直到某个 goroutine 主动尝试从中读取。函数 a
派生出一个 goroutine,该 goroutine 将尝试读取一次 (go b(...)
),然后写入并因此等待至少一个 reader 读取。函数b
立即开始读取,等待数据。这解除了函数 a
的阻塞,它现在可以写入一些整数值。函数 a
现在可以衍生出另一个 b
的实例,它开始读取;这可能发生在获得值的 b
开始调用 fmt.Println
之前、期间或之后。 b
的第二个实例现在必须等待某人——在本例中是 always 函数 a
,运行 循环——发送另一个值,但 a
会尽快执行此操作。 b
的第二个实例现在可以开始调用 fmt.Println
,但它可能(主要是随机的)还没有机会这样做。 b
的第一个实例可能已经在 fmt.Println
中,或者可能还没有,第二个实例可能 运行 第一个——或者可能 both 稍等片刻,b
的 第三个 实例启动,从通道中读取一些值,依此类推。
无法保证 b
的哪个 实例实际进入 fmt.Println
,因此您的值看到印刷品将以某种半随机顺序出现。如果您希望各种 b
实例自行排序,它们将需要以某种方式执行此操作。