使用goroutine和channel实现生产者-消费者模型(Producer-Consumer Model)

117 阅读1分钟
package main

import (
	"bufio"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"sync"
	"time"
)

// 使用goroutine和channel实现生产者-消费者模型(Producer-Consumer Model)
// 要求能够动态调整生产者和消费者数量
// 可以使用内存通道或带缓冲区的通道

var status bool = false
var dChan = make(chan int, 1)

func main() {
	var producerNum int
	var consumerNum int
	flag.IntVar(&producerNum, "p", 1, "生产者数量")
	flag.IntVar(&consumerNum, "c", 2, "消费者数量")
	fmt.Println(producerNum, consumerNum)
	for i := 0; i < consumerNum; i++ {
		go func(dChan chan int, i int) {
			consumer(dChan, i)
		}(dChan, i)
	}
	var sync sync.WaitGroup
	for i := 0; i < producerNum; i++ {
		sync.Add(1)
		go func(dChan chan int, i int) {
			defer sync.Done()
			producer(dChan, i)
		}(dChan, i)
	}
	for {
		reader := bufio.NewReader(os.Stdin)
		fmt.Print("Enter Exit Y/N: ")
		exitData, _ := reader.ReadString('\n')
		fmt.Println(exitData)
		if exitData[:len(exitData)-1] == "Y" {
			status = true
			sync.Wait()
			close(dChan)
			break
		}
	}

}

func producer(dChan chan int, pNum int) {
	rand.Seed(time.Now().UnixNano())
	for !status {
		data := rand.Intn(10000)
		fmt.Printf("生产者%d生产的数据:%d\n", pNum, data)
		dChan <- data
		time.Sleep(200 * time.Millisecond)
	}
}

func consumer(dChan chan int, cNum int) {
	for {
		for item := range dChan {
			fmt.Printf("消费者%d消费的数据:%d\n", cNum, item)
			time.Sleep(100 * time.Millisecond)
		}
	}
}