博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang脱坑指南: goroutine(不断更新)
阅读量:4509 次
发布时间:2019-06-08

本文共 2063 字,大约阅读时间需要 6 分钟。

源代码与测试代码 https://github.com/YJZhangChina/GNP/tree/master/basic 下 goroutine_traps.go 与 goroutine_traps_test.go

1. 不安全的指针传递

Goroutine的调度次序未知,如果执行多次有指针传递的函数,且函数内存在写操作,需要考虑脏读和原子性问题。定义了Message结构体存储当前值current,valueChange方法用于修改current为当前步骤数step,并用Message指导后续操作。多次运goroutine执行该方法,由于指针传递,Message实例仅有一份,goroutine无法保证函数流程的原子性,造成了写无效和脏读。适当增大循环次数size可更容易发现该问题。

Testing UnsafePointerPassing in GoroutineTraps // 模拟结果可能不同After step 9 the value is 9. After step 0 the value is 0. After step 1 the value is 1. After step 2 the value is 2. After step 3 the value is 3. After step 4 the value is 4. After step 7 the value is 7. After step 8 the value is 8. After step 5 the value is 5. After step 6 the value is 5. // Error

指针传递前对Message实例进行克隆,产生写时复制的效果,修改后的结果不受影响。

Testing SafePointerPassing in GoroutineTraps // 模拟结果可能不同After step 0 the value is 0.After step 9 the value is 9.After step 5 the value is 5.After step 6 the value is 6.After step 7 the value is 7.After step 8 the value is 8.After step 2 the value is 2.After step 1 the value is 1.After step 3 the value is 3.After step 4 the value is 4.

goroutine_traps.go

package basicimport (	"fmt"	"sync")type Message struct {	current int}func valueChange(step int, message *Message, waiter *sync.WaitGroup) {	message.current = step	fmt.Printf("After step %d the value is %d.\n", step, message.current)	waiter.Done()}

goroutine_traps_test.go

package basicimport (	"fmt"	"sync"	"testing")func TestUnsafePointerPassing(t *testing.T) {	fmt.Println("Testing UnsafePointerPassing in GoroutineTraps")	size := 10	var waiter sync.WaitGroup	waiter.Add(size)	message := &Message{current: 1}	for i := 0; i < size; i++ {		go valueChange(i+1, message, &waiter)	}	waiter.Wait()}func TestSafePointerPassing(t *testing.T) {	fmt.Println("Testing SafePointerPassing in GoroutineTraps")	size := 10	var waiter sync.WaitGroup	waiter.Add(size)	message := &Message{current: 1}	for i := 0; i < 10; i++ {		var clone = new(Message)		*clone = *message		go valueChange(i+1, clone, &waiter)	}	waiter.Wait()}

 

转载于:https://www.cnblogs.com/miluroe/p/10993210.html

你可能感兴趣的文章
创建空间参考
查看>>
TestFlight下载app 初使用
查看>>
promise学习
查看>>
在vagrant官网下载各种最新.box资源
查看>>
selenium+python自动化95-弹出框死活定位不到
查看>>
关于防止用户表单多次提交方案的思考
查看>>
MAC终端显示tree命令
查看>>
Dissecting the First C# Program "HelloWorld"
查看>>
多线程--生产者消费者--简单例子
查看>>
Mac 安装tensorflow
查看>>
jsoup html解析器 实现对博客园博文标题链接抓取
查看>>
数据库面试题
查看>>
Flex 延时控制三步走
查看>>
T-SQL表联接查询
查看>>
143. Sort Colors II
查看>>
iOS开发UI篇—简单的浏览器查看程序
查看>>
Jmeter响应数据中文乱码
查看>>
androidStudio开发插件整理(但愿人长久,搬砖不再有)
查看>>
topk 问题 --转载
查看>>
java集合系列之LinkedList源码分析
查看>>