Go并发模式之 约束

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013862108/article/details/88623218
约束:
在编写并发代码的时候,有以下几种不同的保证操作安全的方法。
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。 由于词法范围的原因,我们已经不可能执行错误的操作,所以我们不需要通过通信完成内存访问同步  或 共享数据。

猜你喜欢

转载自blog.csdn.net/u013862108/article/details/88623218
今日推荐