[Go] golang buffer channel to manage a group of goroutine work

passageway
1. When a resource needs to be shared between goroutines, the channel sets up a pipeline between goroutines
2. No buffer channel and buffered channel. The second parameter of make is buffer size
3. The bufferless channel needs to be ready for sending and receiving, otherwise the goroutine executed first will block waiting
4. For the buffered channel, before the buffer is full, the transmit and receive actions will not block, and only when the buffer is empty will the receive block

time.Now().Unix() current time stamp time.milliseconds
time.Sleep(1 * time.Second) sleep for one second

 

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

const (
	//Global constant
	numberGoroutines = 4  //Number of goroutine used
	taskLoad         = 10 //Workload to be handled
)

var wg sync.WaitGroup

//init function will execute before main
func init() {
	//Initialize random number
	rand.Seed(time.Now().Unix())
}
func main() {
	//Create buffered channel management, buffer is 10
	tasks := make(chan string, taskLoad)

	//Start 4 goroutines to handle the work
	wg.Add(numberGoroutines) //Add count semaphore
	for i := 1; i <= numberGoroutines; i++ {
		go worker(tasks, i)
	}

	//The main goroutine sends 10 strings to the channel, simulating the work of distributing to the sub goroutine
	for j := 1; j <= taskLoad; j++ {
		tasks <- fmt.Sprintf("Task: %d", j)
	}
	//After sending, close the channel
	close(tasks)
	//If you plug the channel all the way, the sub goroutine can work all the time and can be used as a queue
	// for {
	// 	tasks <- fmt.Sprintf("Task: %d", rand.Int63n(10000000000))
	// }

	//Wait for all goroutines to finish
	wg.Wait()
}

//Processing work
func worker(tasks chan string, worker int) {
	defer wg.Done()
	//Infinite loop processing the received work, you can continue to process the next work after finishing one
	for {
		//From the closed channels, data can still be received and a channel type zero value is returned. If none is received, it will block
		//After receiving one, it will continue to execute
		task, ok := <-tasks
		//Judge whether the channel is empty and closed
		if !ok {
			fmt.Printf("Worker: %d:Close\n", worker)
			//Get out of this goroutine
			return
		}
		//Start work formally
		fmt.Printf("Worker: %d:Start-up\n", worker)
		//Simulating execution with random sleep
		sleep := rand.Int63n(100)
		time.Sleep(time.Duration(sleep) * time.Millisecond)
		//Display completed
		fmt.Printf("Worker: %d :complete %s \n", worker, task)
	}
}

Tags: Go Unix

Posted on Wed, 04 Dec 2019 00:50:50 -0500 by kyberfabrikken