在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
goroutine go中使用Goroutine来实现并发concurrently。 Goroutine是Go语言特有的名词。区别于进程Process,线程Thread,协程Coroutine,因为Go语言的创造者们觉得和他们是有所区别的,所以专门创造了Goroutine。 Goroutine是与其他函数或方法同时运行的函数或方法。Goroutines可以被认为是轻量级的线程。与线程相比,创建Goroutine的成本很小,它就是一段代码,一个函数入口。以及在堆上为其分配的一个堆栈(初始大小为4K,会随着程序的执行自动增长删除)。因此它非常廉价,Go应用程序可以并发运行数千个Goroutines。 package main import ( "fmt" "time" ) func hello() { fmt.Println("Hello world goroutine") } func main() { go hello() time.Sleep(50 * time.Microsecond) fmt.Println("main function") } 临界资源安全问题: 首先看代码: package main import ( "time" "math/rand" "fmt" ) //全局变量 var ticket = 10 // 100张票 func main() { /* 4个goroutine,模拟4个售票口,4个子程序操作同一个共享数据。 */ go saleTickets("售票口a") // g1,100 go saleTickets("售票口b") // g2,100 go saleTickets("售票口c") //g3,100 go saleTickets("售票口d") //g4,100 time.Sleep(5*time.Second) } func saleTickets(name string) { rand.Seed(time.Now().UnixNano()) //for i:=1;i<=100;i++{ // fmt.Println(name,"售出:",i) //} for { //ticket=1 if ticket > 0 { //g1,g3,g2,g4 //睡眠 time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) // g1 ,g3, g2,g4 fmt.Println(name, "售出:", ticket) // 1 , 0, -1 , -2 ticket-- //0 , -1 ,-2 , -3 } else { fmt.Println(name,"没有票了。。") break } } } 执行结果: 售票口b 售出: 10 售票口c 售出: 10 售票口d 售出: 10 售票口c 售出: 7 售票口a 售出: 6 售票口b 售出: 5 售票口d 售出: 4 售票口a 售出: 3 售票口a 售出: 2 售票口d 售出: 1 售票口d 没有票了。。 售票口c 售出: 0 售票口c 没有票了。。 售票口a 售出: -1 售票口a 没有票了。。 售票口b 售出: -2 售票口b 没有票了。。 至于什么原因,做过java的就不解释了,那么go是如何解决这个问题呢 waitgruop 看代码实例: package main import ( "sync" "fmt" ) var wg sync.WaitGroup func main() { wg.Add(2) go fun() go fun2() fmt.Println("main进入阻塞状态。。。等待wg中的子goroutine结束。。") wg.Wait() fmt.Println("jieshu") } func fun(){ defer wg.Done() for i :=0;i<10;i++{ fmt.Println("woshi1 aaaaaaaaaaaa",i) } } func fun2(){ //defer wg.Done() for i :=0;i<10;i++{ fmt.Println("woshi1 ",i) } wg.Done() } main进入阻塞状态。。。等待wg中的子goroutine结束。。 woshi1 aaaaaaaaaaaa 0 woshi1 0 woshi1 1 woshi1 2 woshi1 3 woshi1 4 woshi1 5 woshi1 6 woshi1 7 woshi1 8 woshi1 9 woshi1 aaaaaaaaaaaa 1 woshi1 aaaaaaaaaaaa 2 woshi1 aaaaaaaaaaaa 3 woshi1 aaaaaaaaaaaa 4 woshi1 aaaaaaaaaaaa 5 woshi1 aaaaaaaaaaaa 6 woshi1 aaaaaaaaaaaa 7 woshi1 aaaaaaaaaaaa 8 woshi1 aaaaaaaaaaaa 9 jieshu wg.wait方法,表示程序进入阻塞,等待其他goroutine执行完,再去执行线程下的代码 wg.add方法 表示添加几个goroutine wg.done表示goroutine的代码执行完成了 lock: 看代码实例: package main import ( "fmt" "time" "math/rand" "sync" ) //全局变量,表示票 var ticket1 = 10 //100张票 var mutex sync.Mutex //创建锁头 var wg sync.WaitGroup //同步等待组对象 func main() { /* 4个goroutine,模拟4个售票口, 在使用互斥锁的时候,对资源操作完,一定要解锁。否则会出现程序异常,死锁等问题。 defer语句 */ wg.Add(4) go saleTickets1("售票口1") go saleTickets1("售票口2") go saleTickets1("售票口3") go saleTickets1("售票口4") wg.Wait() //main要等待 fmt.Println("程序结束了。。。") //time.Sleep(5*time.Second) } func saleTickets1(name string){ rand.Seed(time.Now().UnixNano()) defer wg.Done() for{ //上锁 mutex.Lock() //g2 if ticket1 > 0{ //ticket 1 g1 time.Sleep(time.Duration(rand.Intn(1000))*time.Millisecond) fmt.Println(name,"售出:",ticket1) // 1 ticket1-- // 0 }else{ mutex.Unlock() //条件不满足,也要解锁 fmt.Println(name,"售罄,没有票了。。") break } mutex.Unlock() //解锁 } }
执行结果: GOROOT=D:\go\go1.13.6.windows-amd64\go #gosetup GOPATH=D:\go\go1.13.6.windows-amd64\go\GOPATH #gosetup D:\go\go1.13.6.windows-amd64\go\bin\go.exe build -i -o C:\Users\cxy\AppData\Local\Temp\___go_build_waut_go.exe D:/go/work/learngo/lerango/string/waut.go #gosetup "D:\Program Files\JetBrains\ideaIU-2018.1.2.win\bin\runnerw.exe" C:\Users\cxy\AppData\Local\Temp\___go_build_waut_go.exe #gosetup 售票口1 售出: 10 售票口1 售出: 9 售票口2 售出: 8 售票口3 售出: 7 售票口4 售出: 6 售票口1 售出: 5 售票口2 售出: 4 售票口3 售出: 3 售票口4 售出: 2 售票口1 售出: 1 售票口2 售罄,没有票了。。 售票口4 售罄,没有票了。。 售票口3 售罄,没有票了。。 售票口1 售罄,没有票了。。 程序结束了。。。 Process finished with exit code 0 还有读写锁,也是如此:
channel package main import ( "fmt" "time" ) func main() { ch1 := make(chan int) bools := make(chan bool) go func() { fmt.Println("1111 执行") time.Sleep(3* time.Second) data := <-ch1 fmt.Println(data) bools <- true }() time.Sleep(5*time.Second) ch1 <-100 a :=<- bools fmt.Println(a) fmt.Println("main。。over") } 结果: GOROOT=D:\go\go1.13.6.windows-amd64\go #gosetup GOPATH=D:\go\go1.13.6.windows-amd64\go\GOPATH #gosetup D:\go\go1.13.6.windows-amd64\go\bin\go.exe build -i -o C:\Users\cxy\AppData\Local\Temp\___go_build_cha_go.exe D:/go/work/learngo/lerango/string/cha.go #gosetup "D:\Program Files\JetBrains\ideaIU-2018.1.2.win\bin\runnerw.exe" C:\Users\cxy\AppData\Local\Temp\___go_build_cha_go.exe #gosetup 1111 执行 100 true main。。over Process finished with exit code 0
|
请发表评论