最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于golang高并發(fā)的實(shí)現(xiàn)與注意事項(xiàng)說(shuō)明

 更新時(shí)間:2021年05月08日 11:06:17   作者:HandsomeBoy@Guess  
這篇文章主要介紹了關(guān)于golang高并發(fā)的實(shí)現(xiàn)與注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一、并發(fā)的意義

并發(fā)的意義就是讓 一個(gè)程序同時(shí)做多件事情,其目的只是為了能讓程序同時(shí)做另一件事情而已,而不是為了讓程序運(yùn)行的更快(如果是多核處理器,而且任務(wù)可以分成相互獨(dú)立的部分,那么并發(fā)確實(shí)可以讓事情解決的更快)。

golang從語(yǔ)言級(jí)別上對(duì)并發(fā)提供了支持,而且在啟動(dòng)并發(fā)的方式上直接添加了語(yǔ)言級(jí)的關(guān)鍵字,不必非要按照固定的格式來(lái)定義線(xiàn)程函數(shù),也不必因?yàn)閱?dòng)線(xiàn)程的時(shí)候只能給線(xiàn)程函數(shù)傳遞一個(gè)參數(shù)而煩惱。

二、并發(fā)的啟動(dòng)

go的并發(fā)啟動(dòng)非常簡(jiǎn)單,幾乎沒(méi)有什么額外的準(zhǔn)備工作,要并發(fā)的函數(shù)和一般的函數(shù)沒(méi)有什么區(qū)別,參數(shù)隨意,啟動(dòng)的時(shí)候只需要加一個(gè)go關(guān)鍵之即可,其最精髓的部分在于這些協(xié)程(協(xié)程類(lèi)似于線(xiàn)程,但是是更輕量的線(xiàn)程)的調(diào)度。

package main
 
import (
 "fmt"
 "time"
)
 
func comFunc() {
 fmt.Println("This is a common function.")
}
 
func main() {
 go comFunc()
 time.Sleep(time.Second * 3)
}

三、協(xié)程間的同步與通信

1、sync.WaitGroup

sync包中的WaitGroup實(shí)現(xiàn)了一個(gè)類(lèi)似任務(wù)隊(duì)列的結(jié)構(gòu),你可以向隊(duì)列中加入任務(wù),任務(wù)完成后就把任務(wù)從隊(duì)列中移除,如果隊(duì)列中的任務(wù)沒(méi)有全部完成,隊(duì)列就會(huì)觸發(fā)阻塞以阻止程序繼續(xù)運(yùn)行,具體用法參考如下代碼:

package main
import (
 "fmt"
 "sync"
)
var waitGroup sync.WaitGroup
func Afunction(index int) {
 fmt.Println(index)
 waitGroup.Done() //任務(wù)完成,將任務(wù)隊(duì)列中的任務(wù)數(shù)量-1,其實(shí).Done就是.Add(-1)
}
 
func main() {
 for i := 0; i < 10; i++ {
  waitGroup.Add(1) //每創(chuàng)建一個(gè)goroutine,就把任務(wù)隊(duì)列中任務(wù)的數(shù)量+1
  go Afunction(i)
 }
 waitGroup.Wait() //.Wait()這里會(huì)發(fā)生阻塞,直到隊(duì)列中所有的任務(wù)結(jié)束就會(huì)解除阻塞
}

2、channel

channel是一種golang內(nèi)置的類(lèi)型,英語(yǔ)的直譯為"通道",其實(shí),它真的就是一根管道,而且是一個(gè)先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。

我們能對(duì)channel進(jìn)行的操作只有4種:

(1) 創(chuàng)建chennel (通過(guò)make()函數(shù))

(2) 放入數(shù)據(jù) (通過(guò) channel <- data 操作)

(3) 取出數(shù)據(jù) (通過(guò) <-channel 操作)

(4) 關(guān)閉channel (通過(guò)close()函數(shù))

channel的3種性質(zhì)入如下:

(1) channel是一種自動(dòng)阻塞的管道。

如果管道滿(mǎn)了,一個(gè)對(duì)channel放入數(shù)據(jù)的操作就會(huì)阻塞,直到有某個(gè)routine從channel中取出數(shù)據(jù),這個(gè)放入數(shù)據(jù)的操作才會(huì)執(zhí)行。相反同理,如果管道是空的,一個(gè)從channel取出數(shù)據(jù)的操作就會(huì)阻塞,直到某個(gè)routine向這個(gè)channel中放入數(shù)據(jù),這個(gè)取出數(shù)據(jù)的操作才會(huì)執(zhí)行。這是channel最重要的一個(gè)性質(zhì)!?。?/p>

package main
func main() {
 ch := make(chan int, 3)
 ch <- 1
 ch <- 1
 ch <- 1
 ch <- 1 //這一行操作就會(huì)發(fā)生阻塞,因?yàn)榍叭械姆湃霐?shù)據(jù)的操作已經(jīng)把channel填滿(mǎn)了
}
package main
func main() {
 ch := make(chan int, 3)
 <-ch //這一行會(huì)發(fā)生阻塞,因?yàn)閏hannel才剛創(chuàng)建,是空的,沒(méi)有東西可以取出
}

(2)channel分為有緩沖的channel和無(wú)緩沖的channel。

兩種channel的創(chuàng)建方法如下:

ch := make(chan int)  //無(wú)緩沖的channel,同等于make(chan int, 0)
ch := make(chan int, 5) //一個(gè)緩沖區(qū)大小為5的channel

無(wú)緩沖通道與有緩沖通道的主要區(qū)別為:無(wú)緩沖通道存取數(shù)據(jù)是同步的,即如果通道中無(wú)數(shù)據(jù),則通道一直處于阻塞狀態(tài);有緩沖通道存取數(shù)據(jù)是異步的,即存取數(shù)據(jù)互不干擾,只有當(dāng)通道中已滿(mǎn)時(shí),存數(shù)據(jù)操作,通道阻塞;當(dāng)通道中為空時(shí),取數(shù)據(jù)操作,通道阻塞。

因此,使用無(wú)緩沖的channel時(shí),放入操作和取出操作不能在同一個(gè)routine中,而且應(yīng)該是先確保有某個(gè)routine對(duì)它執(zhí)行取出操作,然后才能在另一個(gè)routine中執(zhí)行放入操作,否則會(huì)發(fā)生死鎖現(xiàn)象,示例如下:

package main 
import (
 "fmt"
 "sync"
)
 
var waitGroup sync.WaitGroup //使用wg等待所有routine執(zhí)行完畢,并輸出相應(yīng)的提示信息
 
func AFunc(ch chan int) {
 waitGroup.Add(1)
FLAG:
 for {
  select {
  case val := <-ch:
   fmt.Println(val)
   break FLAG
  }
 }
 waitGroup.Done()
 fmt.Println("WaitGroup Done")
}
 
func main() {
 
 ch := make(chan int) //無(wú)緩沖通道
 execMode := 0        //執(zhí)行模式 0:先啟動(dòng)并發(fā),正常輸出100 1:后啟動(dòng)并發(fā),發(fā)生死鎖
 switch execMode {
 case 0:
  go AFunc(ch)
  ch <- 100
 case 1:
  ch <- 100
  go AFunc(ch)
 }
 waitGroup.Wait()
 close(ch)
}

使用帶緩沖的channel時(shí),因?yàn)橛芯彌_空間,所以只要緩沖區(qū)不滿(mǎn),放入操作就不會(huì)阻塞,同樣,只要緩沖區(qū)不空,取出操作就不會(huì)阻塞。

而且,帶有緩沖的channel的放入和取出操作可以用在同一個(gè)routine中。

但是,一定要注意放入和取出的速率問(wèn)題,否則也會(huì)發(fā)生死鎖現(xiàn)象,示例如下:

package main
import (
 "fmt"
 "sync"
)
var waitGroup sync.WaitGroup
func AFunc(ch chan int, putMode int) {
 val := <-ch
 switch putMode {
 case 0:
  fmt.Printf("Vaule=%d\n", val)
 case 1:
  fmt.Printf("Vaule=%d\n", val)
  for i := 1; i <= 5; i++ {
   ch <- i * val
  }
 case 2:
  fmt.Printf("Vaule=%d\n", val)
  for i := 1; i <= 5; i++ {
   <-ch
  }
 }
 
 waitGroup.Done()
 fmt.Println("WaitGroup Done", val)
}
 
func main() {
 ch := make(chan int, 10)
 putMode := 0 //該模式下,能夠正常輸出所有數(shù)據(jù)
 //putMode := 1//當(dāng)放入速度遠(yuǎn)大于取數(shù)速度時(shí),程序阻塞
 //putMode := 2//當(dāng)取數(shù)速度遠(yuǎn)大于放數(shù)速度時(shí),程序阻塞
 for i := 0; i < 1000; i++ {
  ch <- i
  waitGroup.Add(1)
  go AFunc(ch, putMode)
 }
 waitGroup.Wait()
 close(ch)
}

(3)關(guān)閉后的channel可以取數(shù)據(jù),但是不能放數(shù)據(jù)。

而且,channel在執(zhí)行了close()后并沒(méi)有真的關(guān)閉,channel中的數(shù)據(jù)全部取走之后才會(huì)真正關(guān)閉。

package main
func main() {
 ch := make(chan int, 5)
 ch <- 1
 ch <- 1
 close(ch)
 ch <- 1 //不能對(duì)關(guān)閉的channel執(zhí)行放入操作
        
        // 會(huì)觸發(fā)panic
}
package main
func main() {
 ch := make(chan int, 5)
 ch <- 1
 ch <- 1
 close(ch)
 <-ch //只要channel還有數(shù)據(jù),就可能執(zhí)行取出操作
 
        //正常結(jié)束
}
package main 
import "fmt" 
func main() {
 ch := make(chan int, 5)
 ch <- 1
 ch <- 1
 ch <- 1
 ch <- 1
 close(ch)  //如果執(zhí)行了close()就立即關(guān)閉channel的話(huà),下面的循環(huán)就不會(huì)有任何輸出了
 for {
  data, ok := <-ch
  if !ok {
   break
  }
  fmt.Println(data)
 }
 
 // 輸出:
 // 1
 // 1
 // 1
 // 1
 // 
 // 調(diào)用了close()后,只有channel為空時(shí),channel才會(huì)真的關(guān)閉
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • go語(yǔ)言接口用法實(shí)例分析

    go語(yǔ)言接口用法實(shí)例分析

    這篇文章主要介紹了go語(yǔ)言接口用法,實(shí)例分析了Go語(yǔ)言接口的定義及使用技巧,需要的朋友可以參考下
    2015-03-03
  • 詳解如何使用Golang擴(kuò)展Envoy

    詳解如何使用Golang擴(kuò)展Envoy

    這篇文章主要為大家介紹了詳解如何使用Golang擴(kuò)展Envoy實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Golang爬蟲(chóng)框架colly使用淺析

    Golang爬蟲(chóng)框架colly使用淺析

    這篇文章主要介紹了Golang爬蟲(chóng)框架colly的使用,colly是Go實(shí)現(xiàn)的比較有名的一款爬蟲(chóng)框架,而且Go在高并發(fā)和分布式場(chǎng)景的優(yōu)勢(shì)也正是爬蟲(chóng)技術(shù)所需要的,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05
  • Golang實(shí)現(xiàn)HTTP編程請(qǐng)求和響應(yīng)

    Golang實(shí)現(xiàn)HTTP編程請(qǐng)求和響應(yīng)

    本文主要介紹了Golang實(shí)現(xiàn)HTTP編程請(qǐng)求和響應(yīng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • golang testing使用示例小結(jié)

    golang testing使用示例小結(jié)

    golang自帶了testing測(cè)試包,使用該包可以進(jìn)行自動(dòng)化的單元測(cè)試,輸出結(jié)果驗(yàn)證,并且可以測(cè)試性能,下面通過(guò)示例代碼給大家講解golang testing使用示例小結(jié),感興趣的朋友一起看看吧
    2024-05-05
  • 實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解

    實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解

    這篇文章主要為大家介紹了實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫(kù)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Golang使用http協(xié)議實(shí)現(xiàn)心跳檢測(cè)程序過(guò)程詳解

    Golang使用http協(xié)議實(shí)現(xiàn)心跳檢測(cè)程序過(guò)程詳解

    這篇文章主要介紹了Golang使用http協(xié)議實(shí)現(xiàn)心跳檢測(cè)程序過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-03-03
  • Go語(yǔ)言二進(jìn)制文件的讀寫(xiě)操作

    Go語(yǔ)言二進(jìn)制文件的讀寫(xiě)操作

    本文主要介紹了Go語(yǔ)言二進(jìn)制文件的讀寫(xiě)操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go語(yǔ)言函數(shù)學(xué)習(xí)教程

    Go語(yǔ)言函數(shù)學(xué)習(xí)教程

    這篇文章主要介紹了Go語(yǔ)言函數(shù)基本用法,結(jié)合實(shí)例形式分析了Go語(yǔ)言函數(shù)的格式、定義、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-07-07
  • go語(yǔ)言切片去重的3種方式

    go語(yǔ)言切片去重的3種方式

    go語(yǔ)言中的切片是使用非常頻繁的一個(gè)數(shù)據(jù)結(jié)構(gòu),本文主要介紹了go語(yǔ)言切片去重的3種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08

最新評(píng)論

东辽县| 东方市| 虞城县| 格尔木市| 保德县| 邵东县| 蒙自县| 乐亭县| 伊通| 如东县| 灵武市| 阳朔县| 顺义区| 仁布县| 启东市| 景东| 玉屏| 贵州省| 汾阳市| 西和县| 恩平市| 曲麻莱县| 清新县| 娱乐| 宜州市| 巫山县| 山西省| 常熟市| 鄂州市| 云梦县| 海林市| 桦南县| 家居| 五寨县| 囊谦县| 安康市| 江川县| 长沙市| 景德镇市| 遂平县| 庆云县|