package main
import (
"fmt"
"time"
)
func main() {
// 创建缓冲通道
ch := make(chan int, 3)
// 生产者
go func() {
for i := 1; i <= 5; i++ {
ch <- i
fmt.Printf("Sent: %d\n", i)
}
close(ch) // 正确关闭姿势
}()
// 消费者
go func() {
for {
val, ok := <-ch
if !ok {
fmt.Println("Channel closed!")
return
}
fmt.Printf("Received: %d\n", val)
time.Sleep(500 * time.Millisecond) // 模拟处理耗时
}
}()
time.Sleep(3 * time.Second) // 保证演示完整
}
运行结果:
Sent: 1
Sent: 2
Sent: 3
Received: 1
Sent: 4
Received: 2
Sent: 5
Received: 3
Received: 4
Received: 5
Channel closed!
package main
func main() {
// 示例1:关闭已关闭的通道
ch1 := make(chan int)
close(ch1)
// close(ch1) // 运行时panic
// 示例2:向已关闭通道发送数据
ch2 := make(chan int)
go func() { ch2 <- 1 }()
close(ch2)
// ch2 <- 2 // 运行时panic
// 示例3:未初始化的通道
var ch3 chan int
// ch3 <- 1 // 永久阻塞
// <-ch3 // 永久阻塞
// 示例4:未关闭导致的内存泄漏
ch4 := make(chan int)
go func() {
<-ch4 // 永远阻塞
}()
// 忘记关闭导致goroutine泄漏
}
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
operation := func() chan string {
ch := make(chan string)
go func() {
delay := time.Duration(rand.Intn(1500)) * time.Millisecond
time.Sleep(delay)
ch <- "operation completed"
}()
return ch
}
select {
case res := <-operation():
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("Timeout!")
}
}
package main
import (
"fmt"
"sync"
"time"
)
func WorkerPool() {
const workerCount = 3
const taskCount = 10
taskCh := make(chan int, 5)
doneCh := make(chan struct{}, workerCount)
var wg sync.WaitGroup
// 启动工作池
for i := 0; i < workerCount; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for task := range taskCh {
fmt.Printf("Worker %d processing task %d\n", id, task)
time.Sleep(time.Duration(task%3+1) * time.Second)
doneCh <- struct{}{}
}
}(i)
}
// 分发任务
go func() {
for i := 1; i <= taskCount; i++ {
taskCh <- i
}
close(taskCh)
}()
// 进度监控
go func() {
count := 0
for range doneCh {
count++
fmt.Printf("Completed %d/%d tasks\n", count, taskCount)
if count == taskCount {
close(doneCh)
}
}
}()
wg.Wait()
fmt.Println("All tasks completed!")
}
func main() {
WorkerPool()
}
package main
import (
"fmt"
"testing"
"time"
)
func BenchmarkSingleProcess(b *testing.B) {
ch := make(chan int)
go func() {
for i := 0; i < b.N; i++ {
ch <- i
}
close(ch)
}()
for range ch {
// 模拟处理单个元素
time.Sleep(1 * time.Nanosecond)
}
}
func BenchmarkBatchProcess(b *testing.B) {
ch := make(chan []int, 100)
go func() {
batch := make([]int, 0, 1000)
for i := 0; i < b.N; i++ {
batch = append(batch, i)
if len(batch) == 1000 {
ch <- batch
batch = make([]int, 0, 1000)
}
}
if len(batch) > 0 {
ch <- batch
}
close(ch)
}()
for batch := range ch {
// 模拟批量处理
time.Sleep(time.Duration(len(batch)) * time.Nanosecond)
}
}
func main() {
fmt.Println("Single Process:")
fmt.Println(testing.Benchmark(BenchmarkSingleProcess))
fmt.Println("\nBatch Process:")
fmt.Println(testing.Benchmark(BenchmarkBatchProcess))
}
典型测试结果:
Single Process:
BenchmarkSingleProcess-8 1000000 1045 ns/op
Batch Process:
BenchmarkBatchProcess-8 100000 10312 ns/op (等效103 ns/op)
package main
import (
"fmt"
"time"
)
var data int
var ready = make(chan struct{})
func writer() {
data = 42
close(ready) // 关闭操作作为同步点
}
func reader() {
<-ready
fmt.Println("Data:", data) // 保证输出42
}
func main() {
go writer()
go reader()
time.Sleep(1 * time.Second)
}
package main
import (
"fmt"
"sync"
)
type Singleton struct {
value int
}
var instance *Singleton
var once sync.Once
var instanceCh = make(chan *Singleton)
func GetInstance() *Singleton {
once.Do(func() {
go func() {
instance = &Singleton{value: 42}
instanceCh <- instance
}()
})
return <-instanceCh
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
inst := GetInstance()
fmt.Printf("Instance address: %p\n", inst)
}()
}
wg.Wait()
}
package main
import (
"errors"
"fmt"
"sync"
)
func parallelTasks() ([]int, error) {
const workers = 5
results := make(chan int, workers)
errCh := make(chan error, 1)
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
if id == 2 { // 模拟错误
errCh <- errors.New("worker 2 failed")
return
}
results <- id * 10
}(i)
}
go func() {
wg.Wait()
close(results)
close(errCh)
}()
var err error
var res []int
for {
select {
case r, ok := <-results:
if !ok {
results = nil
} else {
res = append(res, r)
}
case e := <-errCh:
if e != nil && err == nil {
err = e
// 取消剩余任务
return nil, err
}
}
if results == nil {
break
}
}
return res, err
}
func main() {
res, err := parallelTasks()
fmt.Println("Results:", res)
fmt.Println("Error:", err)
}
package main
import (
"fmt"
"time"
)
type PressureAwareChannel struct {
ch chan int
backPress chan struct{}
}
func NewPressureAwareChannel(size int) *PressureAwareChannel {
return &PressureAwareChannel{
ch: make(chan int, size),
backPress: make(chan struct{}, 1),
}
}
func (pac *PressureAwareChannel) Send(val int) bool {
select {
case pac.ch <- val:
return true
default:
select {
case pac.backPress <- struct{}{}:
fmt.Println("Backpressure activated!")
default:
}
return false
}
}
func main() {
pac := NewPressureAwareChannel(3)
// 生产者
go func() {
for i := 1; ; i++ {
if !pac.Send(i) {
time.Sleep(1 * time.Second)
i-- // 重试
}
}
}()
// 消费者
go func() {
for {
select {
case val := <-pac.ch:
fmt.Println("Consumed:", val)
time.Sleep(2 * time.Second) // 慢消费
case <-pac.backPress:
fmt.Println("Processing backpressure...")
}
}
}()
select {} // 保持程序运行
}
package main
import (
"fmt"
"reflect"
"time"
)
func channelStatus(ch interface{}) string {
c := reflect.ValueOf(ch)
if c.Kind() != reflect.Chan {
return "Not a channel"
}
// 获取通道状态
state := "open"
if c.IsClosed() {
state = "closed"
}
// 获取缓冲区使用情况
bufferUsage := ""
if c.Cap() > 0 {
length := c.Len()
bufferUsage = fmt.Sprintf("buffer %d/%d", length, c.Cap())
}
return fmt.Sprintf("%s (%s)", state, bufferUsage)
}
func main() {
ch := make(chan int, 3)
ch <- 1
go func() {
time.Sleep(2 * time.Second)
close(ch)
}()
for i := 0; i < 5; i++ {
fmt.Println("Channel status:", channelStatus(ch))
time.Sleep(1 * time.Second)
}
}
通道所有权原则:
性能黄金法则:
错误处理三要素:
生产环境要点:
// 安全关闭模式
func SafeClose(ch chan int) (justClosed bool) {
defer func() {
if recover() != nil {
justClosed = false
}
}()
close(ch) // 如果ch已关闭会panic
return true
}
// 安全发送模式
func SafeSend(ch chan int, value int) (closed bool) {
defer func() {
if recover() != nil {
closed = true
}
}()
ch <- value
return false
}
通过本文的完整示例和模式,开发者可以构建出健壮的并发系统。记住:通道不是银弹,但正确使用时,它们能帮助您编写出清晰、安全且高效的并发代码。