生産者/消費者

王林
リリース: 2024-07-24 11:51:42
オリジナル
247 人が閲覧しました

意味

それぞれ「プロデューサー」と「コンシューマー」と呼ばれる 2 つのプロセスを考えます。プロデューサは周期的なプロセスであり、そのサイクルが完了するたびに情報の特定の部分が生成され、コンシューマはこれを処理する必要があります。コンシューマも循環的なプロセスであり、そのサイクルを通過するたびに、プロデューサによって生成された次の情報を処理できます。簡単な例は、消費者の役割を果たすパンチカードによってパンチされるパンチカードの画像を「情報の一部」として生成する計算プロセスによって示されます。[1]

Producer/Consumer (Produtor/Consumidor)

説明

プロデューサーはアイテムを作成してデータ構造に保存し、コンシューマーはその構造からアイテムを削除して処理します。

消費が生産より多い場合、バッファ (データ構造) が空になり、消費者は消費するものが何もなくなります
消費量が 生産量より 少ない場合、バッファーがいっぱいになり、生産者はアイテムを追加できなくなります。これは制限されたバッファと呼ばれる古典的な問題です。

問題の文脈化

バッファ内の電子メールを公開するプロデューサーと、バッファから電子メールを消費し、電子メールの新しいアクセス パスワードが通知された電子メールが送信されたことを示すメッセージを表示するコンシューマがあるとします。

Goの実装

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)
        }
    }
}


ログイン後にコピー

実装の説明

  • まず、buffer という構造体を作成します。これには、items という文字列の配列と、同時アクセスを管理するための mu というミューテックスのような制御メカニズムが含まれています。
  • 関数は 2 つあります。1 つは add と呼ばれるもので、バッファーの容量は 5 つの項目しかないため、基本的に空き領域がある限り項目をバッファーに追加します。もう 1 つの get 呼び出しは、バッファー内に項目がある場合、最初の要素を返し、その要素をバッファーから削除します。
  • プロデューサーは基本的にループからインデックスを取得し、それをインデックスとダミーの電子メール ドメインを含む str という文字列に連結し、バッファに追加します。遅延をシミュレートするために時間間隔が追加されました。
  • コンシューマ は、少なくとも 1 つの項目がある場合、バッファーから項目を要求します。その後、コンシューマは、バッファに公開されたアイテムの新しいアクセス パスワードが記載された電子メールが送信されたことを通知するメッセージを画面に表示します。

コードリンク: https://github.com/jcelsocosta/race_condition/blob/main/Producerconsumer/buffer/Producerconsumer.go

参照

  1. https://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD123.html#4.1.%20Typical%20Uses%20of%20the%20General%20Semaphore.

参考文献

https://www.cin.ufpe.br/~cagf/if677/2015-2/slides/08_Concorrencia%20(Jorge).pdf

以上が生産者/消費者の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!