@Golang有意义的问题和尚搬家从前,有三个和尚,需要搬家,唯一的要求是要保证搬家前后房内物品布局一致,然后我编不下去了…问如何使用3个goroutine是由1-100的有序输出?分析问题的核心在于如何保证在并发条...
@Golang有意义的问题
和尚搬家
从前,有三个和尚,需要搬家,唯一的要求是要保证搬家前后房内物品布局一致,然后我编不下去了…
问
如何使用3个goroutine是由1-100的有序输出?
分析
问题的核心在于如何保证在并发条件下的有序输出。
主动控制式
package main
import (
"fmt"
"sync"
"time"
)
func main() {
q := make(chan int)
wg := new(sync.WaitGroup)
wg.Add(1)
go func(wg *sync.WaitGroup, q chan<- int) {
defer wg.Done()
defer close(q)
for i := 1; i <= 100; i++ {
q <- i
time.Sleep(time.Microsecond) // 利用休眠实现对生产者的控制,但这种方案不可靠
}
}(wg, q)
for i := 0; i < 3; i++ {
wg.Add(1)
go func(wg *sync.WaitGroup, q <-chan int) {
defer wg.Done()
for {
if v, ok := <-q; ok {
fmt.Println(v)
} else {
return
}
}
}(wg, q)
}
wg.Wait()
}
// 利用WaitGroup实现安全退出,使生产者休眠来进行控制,但是如果消费者的操作是耗时是不可靠谱的,就会变得不可靠
package main
import (
"fmt"
"time"
)
func print(ch <-chan int){
for{
fmt.Println(<-ch)
}
}
func main() {
ch0 :=make(chan int)
ch1 :=make(chan int)
ch2 :=make(chan int)
go print(ch0)
go print(ch1)
go print(ch2)
for i:=1; i<101; i++{
switch{
case i%3 == 0:
ch0 <- i
case i%3 == 1:
ch1 <- i
case i%3 == 2:
ch2 <-i
}
time.Sleep(time.Microsecond)
}
}
// 利用for循环实现安全退出,同样是使生产者休眠来进行控制,但是如果消费者的操作是耗时是不可靠谱的,就会变得不可靠
抢占式
package main
import (
"fmt"
"sync"
"time"
)
func main() {
q := make(chan int)
wg := new(sync.Mutex)
go func( q chan<- int) {
defer close(q)
for i := 1; i <= 100; i++ {
q <- i
}
}(q)
for i := 0; i < 3; i++ {
go func(wg *sync.Mutex, q <-chan int) {
for {
wg.Lock()
if v, ok := <-q; ok {
fmt.Println(v)
wg.Unlock()
} else {
wg.Unlock()
return
}
}
}(wg, q)
}
time.Sleep(time.Second) // 安全退出
}
// 使用互斥锁阻塞其他协程来实现抢占,使用休眠实现安全退出,这种方案是可靠的,但最好能够使用WaitGroup来实现安全退出
package main
import (
"fmt"
"time"
)
func main() {
a := 0
fn := func() int {
a++
return a
}
ch := make(chan int, 1)
defer close(ch)
for i := 0; i < 3; i++ {
go func() {
for {
ch <- 1
n := fn()
if n > 100 {
break
}
fmt.Println(n)
<-ch
}
}()
}
time.Sleep(time.Second) // 安全退出
}
// 使用管道来塞其他协程来实现抢占,使用休眠实现安全退出,这种方案是可靠的,同理,最好能够使用WaitGroup来实现安全退出
沃梦达教程
本文标题为:Golang有意义的问题-并发下的有序输出
猜你喜欢
- Ruby on Rails在Ping ++ 平台实现支付 2023-07-22
- R语言绘图数据可视化pie chart饼图 2022-12-10
- 汇编语言程序设计之根据输入改变屏幕颜色的代码 2023-07-06
- R语言关于二项分布知识点总结 2022-11-30
- Ruby 迭代器知识汇总 2023-07-23
- Golang http.Client设置超时 2023-09-05
- R语言-如何切换科学计数法和更换小数点位数 2022-11-23
- Swift超详细讲解指针 2023-07-08
- Ruby的字符串与数组求最大值的相关问题讨论 2023-07-22
- Go Web开发进阶实战(gin框架) 2023-09-06
