생산자/소비자

王林
풀어 주다: 2024-07-24 11:51:42
원래의
247명이 탐색했습니다.

정의

각각 '생산자'와 '소비자'라는 두 가지 프로세스를 고려합니다. 생산자는 주기적인 프로세스이며, 주기를 거칠 때마다 소비자가 처리해야 하는 정보의 특정 부분을 생성합니다. 소비자 역시 주기적인 프로세스이며, 주기를 거칠 때마다 생산자가 생성한 대로 다음 정보를 처리할 수 있습니다. 간단한 예는 소비자 역할을 하는 펀치 카드에 의해 펀치될 펀치 카드의 "정보 부분" 이미지를 생성하는 계산 프로세스에 의해 제공됩니다.[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)
        }
    }
}


로그인 후 복사

구현 설명

  • 먼저 items라는 문자열 배열과 mu라는 뮤텍스 같은 제어 메커니즘을 포함하는 buffer라는 구조를 생성하여 동시 액세스를 관리합니다.
  • 두 가지 기능이 있습니다. 하나는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!