了解计算机原理
- 进程:计算机资源分配单位
- 线程:cpu处理单位
- 协程:以 特殊机制或者函数实现高并发,又称 轻量级线程
了解Goroutine
- Go Goroutine, go语言中的协程,实现并发。
- 关键字 go
- 初始大小 4k,随着程序执行自动增长和删除
- 实现多线程 并发 执行
package main
import "fmt"
func helloGoroutine() {
for i := 0; i < 100; i++ {
fmt.Println("hello world", i)
}
}
func main() {
go helloGoroutine()
for i := 0; i < 100; i++ {
fmt.Println("main ", i)
}
}
runtime包
package main
import (
"fmt"
"runtime"
"time"
)
func goSchedFunc() {
go func() {
for i := 0; i < 6; i++ {
fmt.Println("goroutine", i)
}
}()
runtime.Gosched()
for i := 0; i < 6; i++ {
fmt.Println("Main goroutine", i)
}
}
func runtimeGoExitFunc() {
go func() {
fmt.Println("Start runtimeGoExitFunc")
test()
fmt.Println("End runtimeGoExitFunc")
}()
time.Sleep(time.Second * 3)
}
func test() {
defer fmt.Println("延时关闭test函数")
runtime.Goexit()
fmt.Println("执行test函数")
}
func main() {
fmt.Println("GoRoot Path", runtime.GOROOT())
fmt.Println("System", runtime.GOOS)
fmt.Println("NumCPU", runtime.NumCPU())
goSchedFunc()
fmt.Println("NumGoroutine", runtime.NumGoroutine())
runtimeGoExitFunc()
}
多线程问题
- 临界资源安全问题。多线程调用共享变量
- 案例:售票问题
package main
import (
"fmt"
"time"
)
func multithreadedSharedVariableMethods() {
shareVariable := 1
go func() {
shareVariable = 2
fmt.Println("GoRoutine shareVariable:", shareVariable)
}()
shareVariable = 3
time.Sleep(1 * time.Second)
fmt.Println("main shareVariable:", shareVariable)
}
func main() {
multithreadedSharedVariableMethods()
}
sync 同步锁
- 锁机制处理多线程抢占资源的问题
- 某个时间段内,只允许一个 goroutine访问共享数据。当goroutine访问完毕,释放锁后,其他goroutine才能访问
- 不要以共享内存的方式去通信,而是以通信方式去共享内存
- 不推荐使用 锁机制。 go语言中! 其他语言基本上都是以锁的方式处理
- go 中鼓励通过 channel 来解决 共享问题
package main
import (
"fmt"
"sync"
"time"
)
var SmLock sync.Mutex
var Swg sync.WaitGroup
var TickerNums = 10
func saleTicketFunc(ticketSeller string) {
for {
if TickerNums > 0 {
fmt.Println("获取票总量:", TickerNums)
TickerNums--
fmt.Println("售票员:", ticketSeller, "卖出1张票", "剩余票的量:", TickerNums)
} else {
fmt.Println("票卖完了!")
break
}
}
}
func saleTicketMainFunc() {
go saleTicketFunc("张三")
go saleTicketFunc("李四")
go saleTicketFunc("王五")
go saleTicketFunc("赵六")
time.Sleep(3 * time.Second)
}
func saleTicketMutexWaitGroupFunc(ticketSeller string) {
for {
SmLock.Lock()
if TickerNums > 0 {
fmt.Println("获取票总量:", TickerNums)
TickerNums--
fmt.Println("售票员:", ticketSeller, "卖出1张票", "剩余票的量:", TickerNums)
} else {
SmLock.Unlock()
fmt.Println("票卖完了!")
break
}
SmLock.Unlock()
}
}
func saleTicketMutexWaitGroupMainFunc() {
Swg.Add(4)
go saleTicketMutexFunc("张三")
go saleTicketMutexFunc("李四")
go saleTicketMutexFunc("王五")
go saleTicketMutexFunc("赵六")
Swg.Wait()
}
func saleTicketMutexFunc(ticketSeller string) {
defer Swg.Done()
for {
SmLock.Lock()
if TickerNums > 0 {
fmt.Println("获取票总量:", TickerNums)
TickerNums--
fmt.Println("售票员:", ticketSeller, "卖出1张票", "剩余票的量:", TickerNums)
} else {
SmLock.Unlock()
fmt.Println("票卖完了!")
break
}
SmLock.Unlock()
}
}
func saleTicketMutexMainFunc() {
go saleTicketMutexFunc("张三")
go saleTicketMutexFunc("李四")
go saleTicketMutexFunc("王五")
go saleTicketMutexFunc("赵六")
time.Sleep(3 * time.Second)
}
func main() {
saleTicketMainFunc()
saleTicketMutexMainFunc()
saleTicketMutexWaitGroupMainFunc()
}
sync.WaitGroup 同步等待组
package main
import (
"fmt"
"runtime"
"sync"
)
var SwgTest sync.WaitGroup
func test1() {
defer SwgTest.Done()
for i := 0; i < 10; i++ {
fmt.Println("T1", i)
}
}
func test2() {
for i := 0; i < 10; i++ {
fmt.Println("T2", i)
}
SwgTest.Done()
}
func main() {
SwgTest.Add(2)
go test1()
runtime.Gosched()
go test2()
SwgTest.Wait()
}
sync 的 锁 Lock + WaitGroup 同步等待组
package main
import (
"fmt"
"sync"
)
var TickerNums2 = 10
var SmLock2 sync.Mutex
var Swg2 sync.WaitGroup
func saleTicketMutexFunc2(ticketSeller string) {
defer Swg2.Done()
for {
SmLock2.Lock()
if TickerNums2 > 0 {
fmt.Println("获取票总量:", TickerNums2)
TickerNums2--
fmt.Println("售票员:", ticketSeller, "卖出1张票", "剩余票的量:", TickerNums2)
} else {
SmLock2.Unlock()
fmt.Println("票卖完了!")
break
}
SmLock2.Unlock()
}
}
func saleTicketMutexWaitGroupMainFunc2() {
Swg2.Add(4)
go saleTicketMutexFunc2("张三")
go saleTicketMutexFunc2("李四")
go saleTicketMutexFunc2("王五")
go saleTicketMutexFunc2("赵六")
Swg2.Wait()
}
func main() {
saleTicketMutexWaitGroupMainFunc2()
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2019-07-02 Python进阶(十二)----re模块