婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > golang 并發編程之生產者消費者詳解

golang 并發編程之生產者消費者詳解

熱門標簽:電話機器人軟件免費 外呼系統用什么卡 壽光微信地圖標注 外呼系統顯本地手機號 涿州代理外呼系統 百度地圖標注后傳給手機 評價高的400電話辦理 阿克蘇地圖標注 excel地圖標注分布數據

golang 最吸引人的地方可能就是并發了,無論代碼的編寫上,還是性能上面,golang 都有絕對的優勢

學習一個語言的并發特性,我喜歡實現一個生產者消費者模型,這個模型非常經典,適用于很多的并發場景,下面我通過這個模型,來簡單介紹一下 golang 的并發編程

go 并發語法

協程 go

協程是 golang 并發的最小單元,類似于其他語言的線程,只不過線程的實現借助了操作系統的實現,每次線程的調度都是一次系統調用,需要從用戶態切換到內核態,這是一項非常耗時的操作,因此一般的程序里面線程太多會導致大量的性能耗費在線程切換上。而在 golang 內部實現了這種調度,協程在這種調度下面的切換非常的輕量級,成百上千的協程跑在一個 golang 程序里面是很正常的事情

golang 為并發而生,啟動一個協程的語法非常簡單,使用 go 關鍵字即可

go func () {
    // do something
}

同步信號 sync.WaitGroup

多個協程之間可以通過 sync.WaitGroup 同步,這個類似于 Linux 里面的信號量

var wg sync.WaitGroup  // 申明一個信號量
wg.Add(1)   // 信號量加一
wg.Done()   // 信號量減一
wg.Wait()   // 信號量為正時阻塞,直到信號量為0時被喚醒

通道 chan

通道可以理解為一個消息隊列,生產者往隊列里面放,消費者從隊列里面取。通道可以使用 close 關閉

ic := make(chan int, 10)  // 申明一個通道
ic - 10        // 往通道里面放
i := - ic      // 從通道里面取
close(ic)       // 關閉通道

生產者消費者實現

定義產品類

這個產品類根據具體的業務需求定義

type Product struct {
    name  int
    value int
}

生產者

如果 stop 標志不為 false,不斷地往通道里面放 product,完成之后信號量完成

func producer(wg *sync.WaitGroup, products chan- Product, name int, stop *bool) {
    for !*stop {
        product := Product{name: name, value: rand.Int()}
        products - product
        fmt.Printf("producer %v produce a product: %#v\n", name, product)
        time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
    }
    wg.Done()
}

消費者

不斷地從通道里面取 product,然后作對應的處理,直到通道被關閉,并且 products 里面為空, for 循環才會終止,而這正是我們期望的

func consumer(wg *sync.WaitGroup, products -chan Product, name int) {
    for product := range products {
        fmt.Printf("consumer %v consume a product: %#v\n", name, product)
        time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
    }
    wg.Done()
}

主線程

var wgp sync.WaitGroup
var wgc sync.WaitGroup
stop := false
products := make(chan Product, 10)
// 創建 5 個生產者和 5 個消費者
for i := 0; i  5; i++ {
    go producer(wgp, products, i, stop)
    go consumer(wgc, products, i)
    wgp.Add(1)
    wgc.Add(1)
}
time.Sleep(time.Duration(1) * time.Second)
stop = true     // 設置生產者終止信號
wgp.Wait()      // 等待生產者退出
close(products) // 關閉通道
wgc.Wait()      // 等待消費者退出

補充:Go并發編程--通過channel實現生產者消費者模型

概述

生產者消費者模型是多線程設計的經典模型,該模型被廣泛的應用到各個系統的多線程/進程模型設計中。

本文介紹了Go語言中channel的特性,并通過Go語言實現了兩個生產者消費者模型。

channel的一些特性

在Go中channel是非常重要的協程通信的手段,channel是雙向的通道,通過channel可以實現協程間數據的傳遞,通過channel也可以實現協程間的同步(后面會有介紹)。

本文介紹的生產者消費者模型主要用到了channel的以下特性:任意時刻只能有一個協程能夠對channel中某一個item進行訪問。

單生產者單消費者模型

把生產者和消費者都放到一個無線循環中,這個和我們的服務器端的任務處理非常相似。生產者不斷的向channel中放入數據,而消費者不斷的從channel中取出數據,并對數據進行處理(打印)。

由于生產者的協程不會退出,所以channel的寫入會永久存在,這樣當channel中沒有放入數據時,消費者端將會阻塞,等待生產者端放入數據。

代碼的實現如下:

package main
import (
    "fmt"
    "time"
)
var ch1 chan int = make(chan int)
var bufChan chan int = make(chan int, 1000)
var msgChan chan int = make(chan int)
func sum(a int, b int) {
    ch1 - a + b
}
// write data to channel
func writer(max int) {
    for {
        for i := 0; i  max; i++ {  // 簡單的向channel中放入一個整數
            bufChan - i
            time.Sleep(1 * time.Millisecond)  //控制放入的頻率
        }
    }
}
// read data fro m channel
func reader(max int) {
    for {
        r := -bufChan
        fmt.Printf("read value: %d\n", r)
    }
    // 通知主線程,工作結束了,這一步可以省略
    msgChan - 1
}
func testWriterAndReader(max int) {
    go writer(max)
    go reader(max)
    // writer 和reader的任務結束了,主線程會得到通知 
    res := -msgChan
    fmt.Printf("task is done: value=%d\n", res)
}
func main() {
    testWriterAndReader(100)
}

多生產者消費者模型

我們可以利用channel在某個時間點只能有一個協程能夠訪問其中的某一個數據,的特性來實現生產者消費者模型。由于channel具有這樣的特性,我們在放數據和消費數據時可以不需要加鎖。

package main
import (
    "time"
    "fmt"
    "os"
)
var ch1 chan int = make(chan int)
var bufChan chan int = make(chan int, 1000)
var msgChan chan string = make(chan string)
func sum(a int, b int) {
    ch1 - a + b
}
// write data to channel
func writer(max int) {
    for {
        for i := 0; i  max; i++ {
            bufChan - i
            fmt.Fprintf(os.Stderr, "%v write: %d\n", os.Getpid(), i)
            time.Sleep(10 * time.Millisecond)
        }
    }
}
// read data fro m channel
func reader(name string) {
    for {
        r := -bufChan
        fmt.Printf("%s read value: %d\n", name, r)
    }
    msgChan - name
}
func testWriterAndReader(max int) {
    // 開啟多個writer的goroutine,不斷地向channel中寫入數據
    go writer(max)
    go writer(max)
    // 開啟多個reader的goroutine,不斷的從channel中讀取數據,并處理數據
    go reader("read1")
    go reader("read2")
    go reader("read3")
    // 獲取三個reader的任務完成狀態
    name1 := -msgChan
    name2 := -msgChan
    name3 := -msgChan
    fmt.Println("%s,%s,%s: All is done!!", name1, name2, name3)
}
func main() {
    testWriterAndReader(100)
}

輸出如下:

read3 read value: 0

80731 write: 0

80731 write: 0

read1 read value: 0

80731 write: 1

read2 read value: 1

80731 write: 1

read3 read value: 1

80731 write: 2

read2 read value: 2

80731 write: 2

... ...

總結

本文通過channel實現了經典的生產者和消費者模型,利用了channel的特性。但要注意,當消費者的速度小于生產者時,channel就有可能產生擁塞,導致占用內存增加,所以,在實際場景中需要考慮channel的緩沖區的大小。

設置了channel的大小,當生產的數據大于channel的容量時,生產者將會阻塞,這些問題都是要在實際場景中需要考慮的。

一個解決辦法就是使用一個固定的數組或切片作為環形緩沖區,而非channel,通過Sync包的機制來進行同步,實現生產者消費者模型,這樣可以避免由于channel滿而導致消費者端阻塞。

但,對于環形緩沖區而言,可能會覆蓋老的數據,同樣需要考慮具體的使用場景。關于環形緩沖區的原理和實現,在分析Sync包的使用時再進一步分析。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • golang并發編程的實現
  • Go并發編程實踐
  • GO語言并發編程之互斥鎖、讀寫鎖詳解
  • Golang Goroutine的使用
  • Go語言學習之goroutine詳解
  • Go并發編程之正確使用goroutine的方法

標簽:重慶 吐魯番 欽州 雞西 蘭州 汕頭 銅川 梅河口

巨人網絡通訊聲明:本文標題《golang 并發編程之生產者消費者詳解》,本文關鍵詞  golang,并發,編程,之,生產者,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang 并發編程之生產者消費者詳解》相關的同類信息!
  • 本頁收集關于golang 并發編程之生產者消費者詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    一区二区三区在线视频观看58 | 久久久亚洲国产美女国产盗摄| 色av综合在线| 91极品视觉盛宴| 7777精品伊人久久久大香线蕉超级流畅 | 国产中文字幕精品| 成人免费看的视频| 欧美性猛交xxxxxx富婆| 日韩女优毛片在线| 中文字幕在线一区免费| 午夜精品久久久久久久久久| 国产一区二区三区在线观看免费视频 | 综合久久久久综合| 天天综合网 天天综合色| 国产原创一区二区三区| 在线观看不卡一区| 久久久久久久久久看片| 亚洲图片自拍偷拍| 国产一区二区导航在线播放| 欧美午夜在线观看| 国产欧美一区二区在线观看| 午夜视频在线观看一区二区| 成人a免费在线看| 日韩区在线观看| 亚洲欧洲日产国产综合网| 日韩精品乱码av一区二区| 亚洲一区二区视频| 久久精品一区二区三区不卡牛牛| 亚洲精品国产精品乱码不99 | 亚洲精品国产a| 国产一区二区免费在线| 欧美日韩国产片| 日韩伦理电影网| 国产精品一区专区| 日韩一卡二卡三卡四卡| 一区二区三区在线高清| 波多野结衣中文字幕一区| 欧美mv日韩mv国产网站app| 亚洲在线一区二区三区| 成人国产精品免费网站| 久久新电视剧免费观看| 日韩国产欧美在线视频| 欧美日韩亚洲国产综合| 亚洲精品视频免费看| av在线不卡电影| 日本一区二区三区四区在线视频 | 蜜桃av一区二区三区| 91精品福利视频| 亚洲精品综合在线| 99久久久久久| 日韩理论片网站| aaa亚洲精品| 国产精品美女久久久久久久久久久| 看片的网站亚洲| 日韩欧美一级在线播放| 午夜视频在线观看一区二区三区| 欧美视频在线观看一区二区| 亚洲男人的天堂网| 欧美在线观看一区二区| 一区二区三区国产| 欧美三级日韩在线| 亚洲国产日韩a在线播放性色| 99久久久久免费精品国产| 国产精品国产自产拍高清av王其| 成人深夜在线观看| 亚洲三级在线看| 91搞黄在线观看| 偷拍日韩校园综合在线| 欧美一区欧美二区| 激情成人综合网| 日本一区二区视频在线| 97精品久久久久中文字幕| 亚洲三级理论片| 欧美日韩亚洲综合一区| 青娱乐精品在线视频| 精品美女被调教视频大全网站| 激情成人综合网| 中文字幕一区二区三区不卡在线 | 成人app软件下载大全免费| 5月丁香婷婷综合| 日本va欧美va精品发布| 久久亚洲一区二区三区四区| 国产一区二区三区香蕉 | 九一九一国产精品| 国产网站一区二区| 色婷婷久久久综合中文字幕| 五月综合激情婷婷六月色窝| 精品999久久久| 成人a区在线观看| 免费看日韩精品| 亚洲同性同志一二三专区| 首页国产丝袜综合| 亚洲影视在线播放| 久久综合色综合88| aaa国产一区| 日韩av不卡一区二区| 日本一区二区三级电影在线观看| 91小宝寻花一区二区三区| 喷白浆一区二区| 亚洲乱码国产乱码精品精98午夜| 日韩一级视频免费观看在线| 91免费观看视频| 国产在线精品一区二区不卡了| 亚洲精品国产无天堂网2021| 欧美精品一区二区高清在线观看| 色综合天天综合在线视频| 国产曰批免费观看久久久| 亚洲第一二三四区| 亚洲日本青草视频在线怡红院| www一区二区| 91精品国产91热久久久做人人| www.亚洲在线| 国产高清亚洲一区| 六月丁香婷婷久久| 日韩黄色在线观看| 亚洲在线视频免费观看| 亚洲欧洲无码一区二区三区| 国产午夜精品一区二区三区四区| 91精品国产色综合久久| 在线影视一区二区三区| 成人av网在线| 成人综合在线网站| 国内精品国产三级国产a久久| 香蕉久久夜色精品国产使用方法| 国产精品久久久爽爽爽麻豆色哟哟 | 一区二区三区不卡视频| 日韩精品一区二区三区视频| 欧美日韩国产精品成人| 99国产精品久| 成人国产精品免费观看动漫| 日本成人在线不卡视频| 亚洲成人先锋电影| 亚洲色图欧洲色图婷婷| 综合久久一区二区三区| 中文字幕一区二区三区视频| 欧美精品一区二区精品网| 日韩你懂的在线观看| 日韩欧美亚洲国产另类| 日韩一卡二卡三卡| 日韩一区二区三区在线| 制服视频三区第一页精品| 91行情网站电视在线观看高清版| av资源站一区| 久久国产精品区| 成人欧美一区二区三区1314| 日本vs亚洲vs韩国一区三区二区| 日韩一卡二卡三卡| 精品一区二区在线观看| 国产女人18毛片水真多成人如厕| 亚洲精品视频在线看| 精品视频在线看| 国产91对白在线观看九色| 亚洲线精品一区二区三区| 成人看片黄a免费看在线| 成人免费视频一区二区| 福利视频网站一区二区三区| 一本到不卡免费一区二区| 91蝌蚪porny成人天涯| 91蜜桃传媒精品久久久一区二区| 激情综合亚洲精品| 成人午夜精品一区二区三区| 色老汉av一区二区三区| 成人免费av在线| 在线观看免费一区| 久久久精品日韩欧美| 色成人在线视频| 日韩欧美中文字幕一区| 国产精品蜜臀在线观看| 亚洲一区二三区| av在线不卡观看免费观看| 91精品欧美福利在线观看| 国产精品久久久久久久久动漫 | 亚洲国产精品嫩草影院| 亚洲欧美一区二区在线观看| 人禽交欧美网站| 色综合色狠狠天天综合色| 日韩一区二区电影网| 亚洲国产欧美一区二区三区丁香婷| 国产高清不卡二三区| 一本到三区不卡视频| 中文字幕+乱码+中文字幕一区| 久久99精品久久只有精品| 一区二区三区产品免费精品久久75| 麻豆国产欧美一区二区三区| 高清不卡在线观看| 国产精品女上位| 成人久久视频在线观看| 国产亚洲一区二区三区| 亚洲大片精品永久免费| 欧美三级中文字| 天天综合色天天| 亚洲综合免费观看高清完整版 | 日韩精品每日更新| 激情文学综合插| 在线视频国产一区| 国产丝袜在线精品| 久久精品人人做人人综合 | 麻豆视频一区二区| 国产日韩欧美高清在线| 国产精品一区二区果冻传媒|