Go并发模式之 约束

博客介绍了编写并发代码时保证操作安全的方法,包括使用共享内存的同步原语、通过通信共享内存同步,还提及隐式并发安全的情况。同时阐述了特定约束和词法约束,以bytes.Buffer为例说明词法约束可避免错误操作,无需额外同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

约束:
在编写并发代码的时候,有以下几种不同的保证操作安全的方法。
1。 用于共享内存的同步原语(如sync.Mutex)
2. 通过通信来 共享内存来进行同步(如 channel)
在并发处理中还有其他几种情况也是隐式并发安全的:
3。 不会发生改变的数据
4。 受到保护的数据

约束:
特定约束,和 词法约束
特定约束:是通过公约实现约束的。 无论是由语言社区, 你所在的团队, 还是你的代码库设置。 在我看来,坚持约束很难在任何规模 的项目上
进行协调。 除非你有工具在每次有人提交代码时对你的代码进行静态分析。
func main() {
	data := make([]int, 4)   //创建一个 数组

	loopData := func(handleData chan<- int) {
		defer close(handleData)
		for i := range data{
			handleData <- data[i]
		}
	}

	handleData := make(chan int)
	go loopData(handleData)

	for num := range handleData{
		fmt.Println(num)
	}
}
//0
//0
//0
//0
按照惯例: 我们只能从 loopData函数访问它。 不能直接 range data
词法约束: 使用词法作用域 公开 用于多个并发进程的正确数据。 这使得做错事是不可能的。回想一下 channel 部分,它讨论的是将channel 的读写处理
暴露给需要它们的并发进程。
func main(){
	chanOwner := func() <-chan int{
		//在chanOwner 函数的词法范围内实例化channel.这将结果写入channel 的处理的范围约束在它下面定义的闭包中。
		results := make(chan int, 5)
		go func() {
			defer close(results)
			for i:=0 ;i<5; i++{
				results <- i
			}
		}()
		return results
	}

	//将channel 的使用约束为只读。
	consumer := func(results <-chan int) {
		for result := range results{
			fmt.Printf("Received: %d\n", result)
		}

		fmt.Println("Done receiving!")
	}

	results := chanOwner()
	consumer(results)

}
channel 是并发安全的, 来看一个使用 不是并发安全的数据结构的约束例子,它是 bytes.Buffer
func main(){
	printData := func(wg *sync.WaitGroup, data []byte){
		defer wg.Done()

		var buff bytes.Buffer
		for _, b := range data{
			fmt.Fprintf(&buff, "%c", b)
		}
		fmt.Println(buff.String())
	}

	var wg sync.WaitGroup
	wg.Add(2)
	data := []byte("golang")
	go printData(&wg, data[:3])
	go printData(&wg, data[3:])

	wg.Wait()
}
//ang
//gol
我们传入切片的不同子集,因此约束了我们开始的goroutine。 由于词法范围的原因,我们已经不可能执行错误的操作,所以我们不需要通过通信完成
内存访问同步  或 共享数据。
我们传入切片的不同子集,因此约束了我们开始的goroutine。 由于词法范围的原因,我们已经不可能执行错误的操作,所以我们不需要通过通信完成内存访问同步  或 共享数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值