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