default分支用于避免select阻塞,使程序在无就绪case时执行默认操作,保持响应性,但需防止忙等待。

Golang中
select
default
case
select
解决方案
select
select
case
case
select
case
default
考虑以下代码示例:
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
select {
case val := <-ch:
fmt.Println("Received:", val)
default:
fmt.Println("No value received")
}
time.Sleep(time.Second * 2) // 模拟一些耗时操作
select {
case ch <- 10:
fmt.Println("Sent value")
default:
fmt.Println("Channel is full")
}
}在这个例子中,第一个
select
ch
default
default
default
第二个
select
ch
default
default
default
没有数据可接收时,使用default避免阻塞的正确姿势?
在并发编程中,非阻塞操作至关重要。如果程序因为等待某个通道而阻塞,可能会导致整个goroutine甚至整个程序失去响应。
default
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
done := make(chan bool)
go func() {
for {
select {
case val := <-ch:
fmt.Println("Received:", val)
default:
fmt.Println("Doing other work...")
time.Sleep(time.Millisecond * 500) // 模拟一些耗时操作
}
select {
case <-done:
fmt.Println("Exiting goroutine")
return
default:
// 继续执行
}
}
}()
time.Sleep(time.Second * 2)
ch <- 10
time.Sleep(time.Second * 1)
done <- true
time.Sleep(time.Millisecond * 100)
}在这个例子中,一个goroutine在一个无限循环中尝试从通道
ch
default
如何正确处理通道已满时,使用default避免阻塞的情况?
当向一个已满的通道发送数据时,如果没有
default
select
default
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 2) // 创建一个容量为2的缓冲通道
ch <- 1
ch <- 2
select {
case ch <- 3:
fmt.Println("Sent value 3")
default:
fmt.Println("Channel is full, value 3 discarded")
}
time.Sleep(time.Second * 1)
fmt.Println("Current channel length:", len(ch))
}在这个例子中,我们创建了一个容量为2的缓冲通道
ch
select
default
在实际应用中,你需要根据具体的需求来决定如何处理通道已满的情况。你可以选择丢弃数据(如上面的例子),也可以选择将数据放入一个队列中,等待通道有空间时再发送。
使用default时可能遇到的坑,以及如何避免?
过度使用
default
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for {
select {
case val := <-ch:
fmt.Println("Received:", val)
default:
// 忙等待
// fmt.Println("Doing nothing...") // 如果打开这行,会看到CPU占用率飙升
}
}
}()
time.Sleep(time.Second * 5)
ch <- 10
time.Sleep(time.Second * 1)
}在这个例子中,goroutine在一个无限循环中不断地检查通道
ch
default
为了避免忙等待,你可以在
default
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for {
select {
case val := <-ch:
fmt.Println("Received:", val)
default:
// 添加延时,避免忙等待
time.Sleep(time.Millisecond * 10)
// fmt.Println("Doing nothing...")
}
}
}()
time.Sleep(time.Second * 5)
ch <- 10
time.Sleep(time.Second * 1)
}添加延时后,CPU占用率会显著降低。
总结来说,
select
default
default
default
以上就是Golang中select语句的default分支在非阻塞操作中的作用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号