我們考慮兩個進程,分別稱為「生產者」和「消費者」。生產者是一個循環過程,每次循環都會產生一定部分的訊息,這些訊息必須由消費者處理。消費者也是一個循環過程,每次它經歷它的週期時,它都可以處理下一個訊息,因為它是由生產者產生的。計算過程給出了一個簡單的例子,該計算過程產生由穿孔卡打孔的穿孔卡的「資訊部分」圖像,穿孔卡扮演消費者的角色。 [1]
生產者建立項目並將其儲存在資料結構中,而消費者則從該結構中刪除項目並處理它們。
如果消費大於生產,則緩衝區(資料結構)清空,消費者沒有任何東西可消費
如果消耗量 小於 生產量,則緩衝區已滿,生產者無法增加更多項目。這是一個經典問題,稱為有限緩衝區。
假設我們有一個生產者在緩衝區中發布一封電子郵件,以及一個消費者使用緩衝區中的電子郵件並顯示一條訊息,表明已發送電子郵件並通知電子郵件的新訪問密碼。
package main import ( "fmt" "os" "strconv" "sync" "time" ) type buffer struct { items []string mu sync.Mutex } func (buff *buffer) add(item string) { buff.mu.Lock() defer buff.mu.Unlock() if len(buff.items) < 5 { buff.items = append(buff.items, item) // fmt.Println("Foi adicionado o item " + item) } else { fmt.Println("O Buffer não pode armazenar nenhum item mais está com a capacidade máxima") os.Exit(0) } } func (buff *buffer) get() string { buff.mu.Lock() defer buff.mu.Unlock() if len(buff.items) == 0 { return "" } target := buff.items[0] buff.items = buff.items[1:] return target } var wg sync.WaitGroup func main() { buff := buffer{} wg.Add(2) go producer(&buff) go consumer(&buff) wg.Wait() } func producer(buff *buffer) { defer wg.Done() for index := 1; ; index++ { str := strconv.Itoa(index) + "@email.com" buff.add(str) time.Sleep(5 * time.Millisecond) // Adiciona um pequeno atraso para simular produção } } func consumer(buff *buffer) { defer wg.Done() for { data := buff.get() if data != "" { fmt.Println("Enviado um email com a nova senha de acesso para: " + data) } } }
程式碼連結: https://github.com/jcelsocosta/race_condition/blob/main/ Producerconsumer/buffer/ Producerconsumer.go
https://www.cin.ufpe.br/~cagf/if677/2015-2/slides/08_Concorrencia%20(Jorge).pdf
以上是生產者/消費者的詳細內容。更多資訊請關注PHP中文網其他相關文章!