最近在测试服务器的 UDP 接口, 最开始我使用 python 协程制造负载, 但是单机负载一直不高. 刚好最近在学习 golang 相关的内容, 就用 golang 实现了一个 UDP 施压的程序. 在编写 golang 程序的过程中经常要用到 goroutine 与 channel. 读取 channel 中的内容是阻塞的, 而且官方似乎没有给出相关的超时处理, 因此需要程序员做相关的超时处理. 一般用 select time.After() 进行超时处理. 代码如下:
代码语言:javascript复制func main() {
go sendToMain()
for {
fmt.Println("run for")
//两个 case. 一个是从管道里面读数据, 另一个是 0.5s 执行.
//当 0.5 秒内未在第一个 case 读取数据时执行第二个 case.
select {
case send_data := <-send_to_main: // 阻塞直到管道可读
fmt.Println("run send_data := <-send_to_main case")
switch send_data {
case 1:
fmt.Println("1")
default:
continue
}
case <-time.After(500 * time.Millisecond): // 0.5s 后管道还不可读则执行这个 case
fmt.Println("run <-time.After(500 * time.Millisecond) case")
break
}
}
}
运行之后我发现 switch 里的 continue 可以跳出本次循环, 但是 select 里的 break 只会结束本次循环, 并不会跳出最外层的 for 循环, 难道外循环还需要些循环控制相关的逻辑吗? 查询相关资料后我发现并不用, 只需在 for 循环上加一个标签, break 到这个标签即可. 代码如下:
代码语言:javascript复制var send_to_main = make(chan int)
func sendToMain() {
for i := 0; i < 10; i {
send_to_main <- i
time.Sleep(1 * time.Second) //阻塞 1 秒
}
}
func main() {
go sendToMain()
SELECT:
for {
fmt.Println("run for")
//两个 case. 一个是从管道里面读数据, 另一个是 0.5s 执行.
//当 0.5 秒内未在第一个 case 读取数据时执行第二个 case.
select {
case send_data := <-send_to_main: // 阻塞直到管道可读
fmt.Println("run send_data := <-send_to_main case")
switch send_data {
case 1:
fmt.Println("1")
default:
// continue SELECT
continue
}
case <-time.After(500 * time.Millisecond): // 0.5s 后管道还不可读则执行这个 case
fmt.Println("run <-time.After(500 * time.Millisecond) case")
break SELECT
}
}
}
我刚刚接触 golang 写的比较简陋, 园里的大佬肯定有更好的方法, 希望各位大佬不吝赐教.