それぞれ「プロデューサー」と「コンシューマー」と呼ばれる 2 つのプロセスを考えます。プロデューサは周期的なプロセスであり、そのサイクルが完了するたびに情報の特定の部分が生成され、コンシューマはこれを処理する必要があります。コンシューマも循環的なプロセスであり、そのサイクルを通過するたびに、プロデューサによって生成された次の情報を処理できます。簡単な例は、消費者の役割を果たすパンチカードによってパンチされるパンチカードの画像を「情報の一部」として生成する計算プロセスによって示されます。[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 中国語 Web サイトの他の関連記事を参照してください。