Solving the cashier problem with goroutines

Before we try to solve the problem, let's first formulate what we want to achieve:

  1. Create a channel orderChannel that accepts all orders.
  2. Launch the required number of cashier goroutines that accept limited numbers of orders from orderChannel.
  3. Start putting all orders into orderChannel.

Let's look at one possible solution that tries to solve the cashier problem using the preceding steps:

// wichan.go 
package main 
 
import ( 
    "fmt" 
    "sync" 
) 
 
func cashier(cashierID int, orderChannel <-chan int, wg *sync.WaitGroup) { 
    // Process orders upto limit. 
    for ordersProcessed := 0; ordersProcessed < 10; ordersProcessed++ { 
        // Retrieve order from orderChannel 
        orderNum := <-orderChannel 
       
        // Cashier is ready to serve! 
        fmt.Println("Cashier ", cashierID, "Processing order", orderNum, "Orders Processed", ordersProcessed) 
        wg.Done() 
    } 
} 
 
func main() { 
    var wg sync.WaitGroup 
    wg.Add(30) 
    ordersChannel := make(chan int) 
 
    for i := 0; i < 3; i++ { 
        // Start the three cashiers 
        func(i int) { 
            go cashier(i, ordersChannel, &wg) 
        }(i) 
    } 
   
    // Start adding orders to be processed. 
    for i := 0; i < 30; i++ { 
        ordersChannel <- i 
    } 
    wg.Wait() 
} 

On running the preceding code with -race flag, we can see that the code ran without any data races:

$ go run -race wichan.go 
Cashier  2 Processing order 2 Orders Processed 0
Cashier  2 Processing order 3 Orders Processed 1
Cashier  0 Processing order 0 Orders Processed 0
Cashier  1 Processing order 1 Orders Processed 0
...
Cashier  0 Processing order 27 Orders Processed 9

The code is quite straightforward, is easy to parallelize, and works well without causing any data races.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset