diff --git a/blog/golang/golang-concurrency.md b/blog/golang/golang-concurrency.md index 9eb00d97f2577d173517d36d377b12a2e965f6c6..20d21fbe330385528e898cdb033aac9ddbac1080 100644 --- a/blog/golang/golang-concurrency.md +++ b/blog/golang/golang-concurrency.md @@ -1,4 +1,4 @@ -# 第二十章 golang 并发编程 +# 第二十章 Golang 并发编程 ## 协程 @@ -793,3 +793,308 @@ func main() { ``` +## Ticker + +Timer只执行一次,Ticker可以周期的执行 + +示例 + +```go +package main + +import ( + "fmt" + "time" +) + +func main() { + // 执行五次打印 + ticker := time.NewTicker(time.Second) + + count := 0 + for _ = range ticker.C { + fmt.Println("ticker") + count++ + + if count >= 5 { + ticker.Stop() + break + } + } + +} + +``` + +示例 + +```go +package main + +import ( + "fmt" + "time" +) + +func main() { + ticker := time.NewTicker(time.Second) + chanInt := make(chan int) + + // 定时向管道随机发送一个数 + go func() { + for _ = range ticker.C { + select { + case chanInt <- 1: + case chanInt <- 2: + case chanInt <- 3: + } + } + }() + + // 接收管道数据 + sum := 0 + for v := range chanInt { + fmt.Printf("v: %v\n", v) + sum += v + if sum >= 10 { + break + } + } + +} + +``` + +## 原子变量 + +不加锁示例 + +```go +package main + +import ( + "fmt" + "time" +) + +var value = 100 + +func add() { + value++ +} + +func sub() { + value-- +} + +func main() { + + for i := 0; i < 100; i++ { + go add() + go sub() + } + + time.Sleep(time.Second * 2) + fmt.Printf("value: %v\n", value) + // value: 101 + +} + + ``` + + 加锁示例 + + ```go + package main + +import ( + "fmt" + "sync" + "time" +) + +var value = 100 + +var lock sync.Mutex + +func add() { + lock.Lock() + value++ + lock.Unlock() +} + +func sub() { + lock.Lock() + value-- + lock.Unlock() +} + +func main() { + + for i := 0; i < 100; i++ { + go add() + go sub() + } + + time.Sleep(time.Second * 2) + fmt.Printf("value: %v\n", value) + // value: 100 + +} + +``` + +atomic示例 + +cas: compare and swap (old new) + +```go +package main + +import ( + "fmt" + "sync/atomic" + "time" +) + +var value int32 = 100 + +func add() { + atomic.AddInt32(&value, 1) +} + +func sub() { + atomic.AddInt32(&value, -1) +} + +func main() { + + for i := 0; i < 100; i++ { + go add() + go sub() + } + + time.Sleep(time.Second * 2) + fmt.Printf("value: %v\n", value) + // value: 100 + +} +``` + +## 原子操作详解 + +atomic 提供的原子操作能够确保任一时刻,只有一个goroutine对变量进行操作 + +善用atomic能够避免程序中出现大量的锁操作 + +atomic常见的操作有: + +- 增减 +- 载入 read +- 比较并交换cas +- 交换 +- 存储 write + +### 增减 + +```go +package main + +import ( + "fmt" + "sync/atomic" +) + +func main() { + + var value int32 = 100 + atomic.AddInt32(&value, 1) + fmt.Printf("value: %v\n", value) + // value: 101 + + atomic.AddInt32(&value, -1) + fmt.Printf("value: %v\n", value) + // value: 100 + +} + +``` + +### 读写 + +```go +package main + +import ( + "fmt" + "sync/atomic" +) + +func main() { + + var value int32 = 100 + + // read + atomic.LoadInt32(&value) + fmt.Printf("value: %v\n", value) + // value: 100 + + // write + atomic.StoreInt32(&value, 200) + fmt.Printf("value: %v\n", value) + // value: 200 + +} + +``` + +### 比较并交换cas + +```go +package main + +import ( + "fmt" + "sync/atomic" +) + +func main() { + + var value int32 = 100 + + // cas + ret := atomic.CompareAndSwapInt32(&value, 100, 200) + + fmt.Printf("ret: %v\n", ret) + // ret: true + + fmt.Printf("value: %v\n", value) + // value: 200 + +} + +``` + +### 交换 + +```go +package main + +import ( + "fmt" + "sync/atomic" +) + +func main() { + + var value int32 = 100 + + // 直接交换 + atomic.SwapInt32(&value, 200) + + fmt.Printf("value: %v\n", value) + // value: 200 + +} + +``` diff --git a/blog/golang/golang-standard.md b/blog/golang/golang-standard.md new file mode 100644 index 0000000000000000000000000000000000000000..b9db4df7ca99bdba94e865a568e84ed7ed62d665 --- /dev/null +++ b/blog/golang/golang-standard.md @@ -0,0 +1,225 @@ +# 第二十一章 Golang标准库 + +标准库文档:https://pkg.go.dev/std + +## os模块 + +os模块实现了平台无关的编程接口 + + +创建文件 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + // 会覆盖原有文件 + file, err := os.Create("demo.txt") + + if err != nil { + fmt.Printf("err: %v\n", err) + } else { + fmt.Printf("file.Name(): %v\n", file.Name()) + // file.Name(): demo.txt + } +} + +``` + +创建目录 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + + // 权限777 + err := os.Mkdir("demo", os.ModePerm) + + if err != nil { + fmt.Printf("err: %v\n", err) + } +} + +``` + +创建多级目录 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + + // 权限777 + err := os.MkdirAll("a/b/demo", os.ModePerm) + + if err != nil { + fmt.Printf("err: %v\n", err) + } +} + +``` + +移除文件或空目录 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + + err := os.Remove("demo.txt") + + if err != nil { + fmt.Printf("err: %v\n", err) + } +} + +``` + +移除目录下所有文件 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + + err := os.RemoveAll("a") + + if err != nil { + fmt.Printf("err: %v\n", err) + } +} +``` + +工作目录 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + + // 获取当前工作目录 + dir, _ := os.Getwd() + + fmt.Printf("dir: %v\n", dir) + // dir: /Users/mo/Desktop/go_code + + // 修改当前工作目录 + os.Chdir("../") + + // 再次获取当前工作目录 + dir, _ = os.Getwd() + + fmt.Printf("dir: %v\n", dir) + // dir: /Users/mo/Desktop +} + +``` + +获取临时目录 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + temp := os.TempDir() + fmt.Printf("temp: %v\n", temp) + // temp: /var/folders/43/llymqbps19d74q2h_bgb00mr0000gn/T/ +} + +``` + +重命名文件 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + err := os.Rename("demo.txt", "demo.2.txt") + if err != nil { + fmt.Printf("err: %v\n", err) + } +} + +``` + +读取文件 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + content, err := os.ReadFile("demo.txt") + if err != nil { + fmt.Printf("err: %v\n", err) + } else { + fmt.Printf("content: %v\n", string(content[:])) + // content: Hello World + } +} + +``` + +写文件 + +```go +package main + +import ( + "fmt" + "os" +) + +func main() { + err := os.WriteFile("demo.txt", []byte("hello"), os.ModePerm) + if err != nil { + fmt.Printf("err: %v\n", err) + } +} + +``` \ No newline at end of file diff --git a/blog/golang/index.md b/blog/golang/index.md index 4cb84812d9c505f7bf2504f48ad1c97403cc273a..92f3b059d7007faa78c0caeba7e87b69270c71fb 100644 --- a/blog/golang/index.md +++ b/blog/golang/index.md @@ -36,9 +36,9 @@ [第十四章 Golang map](/blog/golang/golang-map.md) -[第十五章 Golang 函数](/blog/golang/golang-function.md) +[第十五章 Golang 函数 func](/blog/golang/golang-function.md) -[第十六章 Golang 指针](/blog/golang/golang-pointer.md) +[第十六章 Golang 指针 pointer ](/blog/golang/golang-pointer.md) [第十七章 Golang 结构体 struct](/blog/golang/golang-struct.md) @@ -46,11 +46,12 @@ [第十九章 Golang包 package](/blog/golang/golang-package.md) -[第二十章 golang 并发编程](/blog/golang/golang-concurrency.md) +[第二十章 Golang 并发编程](/blog/golang/golang-concurrency.md) +[第二十一章 Golang标准库](/blog/golang/golang-standard.md) -https://www.bilibili.com/video/BV1ME411Y71o?p=27&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da +https://www.bilibili.com/video/BV1ME411Y71o?p=27&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da -https://www.bilibili.com/video/BV1zR4y1t7Wj/?p=75&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da \ No newline at end of file +https://www.bilibili.com/video/BV1zR4y1t7Wj/?p=78&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da \ No newline at end of file