Skip to content

Commit

Permalink
并发
Browse files Browse the repository at this point in the history
  • Loading branch information
hekuangsheng committed Apr 20, 2022
1 parent 0469bfe commit 3378f2b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
9 changes: 8 additions & 1 deletion golang_CSP.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!--
* @Author: your name
* @Date: 2022-04-19 10:27:41
* @LastEditTime: 2022-04-20 15:24:48
* @LastEditTime: 2022-04-20 20:21:17
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%A
* @FilePath: /golang-base/golang_CSP.md
Expand All @@ -20,6 +20,9 @@

# 并发演进
[并发之痛 Thread,Goroutine,Actor](http://jolestar.com/parallel-programming-model-thread-goroutine-actor/)
1.竞态条件(race conditions) 如果每个任务都是独立的,不需要共享任何资源,那线程也就非常简单。但世界往往是复杂的
2.依赖关系以及执行顺序 如果线程之间的任务有依赖关系,需要等待以及通知机制来进行协调

## Actor CSP
Actor模型非常适用于多个组件独立工作,相互之间仅仅依靠消息传递的情况。如果想在多个组件之间维持一致的状态
1.线程池方案
Expand Down Expand Up @@ -101,3 +104,7 @@ atomic包提供了底层的原子级内存操作,对于同步算法的实现
* [Context](https://github.com/singgel/golang-base/blob/main/sync_context/main.go)
一个任务会有很多个协程协作完成,一次 HTTP 请求也会触发很多个协程的启动,而这些协程有可能会启动更多的子协程,并且无法预知有多少层协程、每一层有多少个协程
Context 就是用来简化解决这些问题的,并且是并发安全的。Context 是一个接口,它具备手动、定时、超时发出取消信号、传值等功能,主要用于控制多个协程之间的协作,尤其是取消操作。一旦取消指令下达,那么被 Context 跟踪的这些协程都会收到取消信号,就可以做清理和退出操作

## race
* [go run -race XXX.go]()
Go语言中单元测试的时候加上-race参数,可以实现并发测试
50 changes: 50 additions & 0 deletions sync_race/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* @Author: your name
* @Date: 2022-04-20 20:01:47
* @LastEditTime: 2022-04-20 20:15:18
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: /golang-base/sync_race/main.go
https://juejin.cn/post/6844903918233714695
go run -race sync_race/main.go
首先,通过 time.AfterFunc 创建 timer,定时的间隔从 randomDuration 函数获得,定时函数打印消息,然后通过 timer 的 Reset 方法重置定时器,重复利用。
*/
package main

import (
"fmt"
"math/rand"
"time"
)

// 程序中存在 2 个 goroutine 非同步读写变量 t。
// 如果初始定时时间非常短,就可能出现在主函数还未对 t 赋值,定时函数已经执行,而此时 t 仍然是 nil,无法调用 Reset 方法。
// func main() {
// start := time.Now()
// var t *time.Timer
// t = time.AfterFunc(randomDuration(), func() {
// fmt.Println(time.Now().Sub(start))
// t.Reset(randomDuration())
// })

// time.Sleep(5 * time.Second)
// }

func main() {
start := time.Now()
reset := make(chan bool)
var t *time.Timer
t = time.AfterFunc(randomDuration(), func() {
fmt.Println(time.Now().Sub(start))
reset <- true
})
for time.Since(start) < 5*time.Second {
<-reset
t.Reset(randomDuration())
}
}

func randomDuration() time.Duration {
return time.Duration(rand.Int63n(1e9))
}

0 comments on commit 3378f2b

Please sign in to comment.