go channel ->同步

通道并非用来取代锁,各有不同使用场景。
通道解决高级别逻辑层次并发架构,锁则用来保护低级别局部代码安全。

竟态条件:多线程同时读写共享资源(竟态资源)。
临界区:读写竟态资源的代码片段。

互斥锁:同一时刻,只有一个线程能进入临界区。
读写锁:写独占(其他读写均被阻塞),读共享。
信号量:允许指定数量线程进入临界区。
自旋锁:失败后,以循环积极尝试。(无上下文切换,小粒度)

悲观锁:操作前独占锁定。
乐观锁:假定无竞争,后置检查。(Lock Free, CAS)

标准库 sync 提供了多种锁,另有原子操作等。

Mutex:互斥锁。
RWMutex:读写锁。

WaitGroup:等待一组任务结束。
Cond:单播或广播唤醒其他任务。
Once:确保只调用一次(函数)。

Map:并发安全字典,(少写多读,数据不重叠)
Pool:对象池。(缓存对象可被回收)

竞争检测

测试阶段,以 -race 编译,注入竞争检查(data race detection)指令。

有较大性能损失,避免在基准测试和发布版本中使用。
有不确定性,不能保证百分百测出。
单元测试有效完整,定期执行竞争检查。

条件变量

内部以计数器和队列作为单播(signal)和广播(broadcast)依据。
引入外部锁作为竟态资源保护,可与其他逻辑同步。

func main() {
	var wg sync.WaitGroup

	cond := sync.NewCond(&sync.Mutex{})
	data := make([]int, 0)

	// 1 写
	wg.Add(1)
	go func() {
		defer wg.Done()

		for i := 0; i < 5; i++ {
            
            // 保护竟态资源。
			cond.L.Lock()
			data = append(data, i + 100)
			cond.L.Unlock()
            
            // 唤醒一个。
			cond.Signal()
		}

        // 唤醒所有(剩余)。
		// cond.Broadcast()
	}()

	// n 读
	for i := 0; i < 5; i++ {
		wg.Add(1)

		go func(id int) {
			defer wg.Done()
            
            // 锁定竟态资源。
			cond.L.Lock()

            // 循环检查是否符合后续操作条件。
            // 如条件不符,则继续等待。
			for len(data) == 0 {
				cond.Wait()
			}

			x := data[0]
			data = data[1:]

			cond.L.Unlock()
			println(id, ":", x)
		}(i)
	}

	wg.Wait()
}

 

 

 

 
 
posted @   codestacklinuxer  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2023-05-11 gin 框架使用
2020-05-11 quic 2 ietf-transport-draft-ietf-quic-transport-09
2019-05-11 linux nf_conntrack 连接跟踪机制
2019-05-11 linux Netfilterr中扩展match target
2019-05-11 linux netfilter ----iptable_filter
2019-05-11 linux netfilter rule match target 数据结构
2019-05-11 linux netfilter 五个钩子点
点击右上角即可分享
微信分享提示