首頁  >  文章  >  後端開發  >  生產者/消費者

生產者/消費者

王林
王林原創
2024-07-24 11:51:42247瀏覽

定義

我們考慮兩個進程,分別稱為「生產者」和「消費者」。生產者是一個循環過程,每次循環都會產生一定部分的訊息,這些訊息必須由消費者處理。消費者也是一個循環過程,每次它經歷它的週期時,它都可以處理下一個訊息,因為它是由生產者產生的。計算過程給出了一個簡單的例子,該計算過程產生由穿孔卡打孔的穿孔卡的「資訊部分」圖像,穿孔卡扮演消費者的角色。 [1]

Producer/Consumer (Produtor/Consumidor)

解釋

生產者建立項目並將其儲存在資料結構中,而消費者則從該結構中刪除項目並處理它們。

如果消費大於生產,則緩衝區(資料結構)清空,消費者沒有任何東西可消費
如果消耗量 小於 生產量,則緩衝區已滿,生產者無法增加更多項目。這是一個經典問題,稱為有限緩衝區

問題的情境化

假設我們有一個生產者在緩衝區中發布一封電子郵件,以及一個消費者使用緩衝區中的電子郵件並顯示一條訊息,表明已發送電子郵件並通知電子郵件的新訪問密碼。

執行

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 的類似互斥體的控制機制,用於管理並發存取。
  • 我們有兩個函數:一個稱為add,它基本上將一個項目添加到緩衝區中,只要有可用空間,因為緩衝區容量只有5 個項目;另一個get 調用,如果緩衝區中有項目,則傳回第一個元素並從緩衝區中刪除該元素。
  • Producer 基本上從循環中獲取索引,並將其連接成一個名為str 的字串,其中包含索引和虛構的電子郵件域,並將其新增到緩衝區。新增了時間間隔來模擬延遲。
  • 消費者從緩衝區請求一個項目(如果它至少有一個項目)。然後,消費者在螢幕上顯示一條訊息,通知已發送一封電子郵件,其中包含緩衝區中發布的項目的新存取密碼。

程式碼連結: 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn