#StackBounty: #go Concurrent processing of a slice

Bounty: 50

I am trying to learn Go concurrency patterns and best practices on my own.
I have invented a simple task for myself.
I want to process a slice of integers in a parallel manner by dividing it into sub-slices and process each with a goroutine.
Below is the solution I have at the moment, I seek constructive code review.
If you have any questions or clarifications/updates are needed, please leave a comment.

//  TASK:
//      given the slice of integers, multiply each element by 10
//      apply concurrency to solve this task by splitting slice into subslices and feeding them to goroutines
//  EXAMPLE:
//      input  -> slice := []int{  1,  2,  3,  4,  5,  6,  7,  8 }
//      output -> slice := []int{ 10, 20, 30, 40, 50, 60, 70, 80 }

package main

import (
    "fmt"
    "sync"
    "time"
)

func simulate_close_signal(quit chan bool, wg *sync.WaitGroup) {
    defer close(quit)
    defer wg.Done() // maybe I can remove this?

    for {
        select {
        case <-time.After(1 * time.Second):
            fmt.Println("Close signal sent")
            return
        }
    }
}

func process_subslice(quit chan bool,
    wg *sync.WaitGroup,
    original_slice []int,
    subslice_starting_index int,
    subslice_ending_index int,
    timeout func()) {

    defer wg.Done()
    for {
        select {
        case <-quit:
            fmt.Println("Goroutine: received request to close, quiting...")
            return
        default:
            // do I need mutex here? I think I don't since each goroutine processes independent subslice...
            original_slice[subslice_starting_index] = original_slice[subslice_starting_index] * 10
            subslice_starting_index++
            if subslice_starting_index >= subslice_ending_index {
                return
            }
            timeout() // added so I can test close signal
        }
    }
}

func main() {

    slice := []int{1, 2, 3, 4, 5, 6, 7, 8}
    fmt.Println("Starting slice: ", slice)

    quit := make(chan bool)

    wg := sync.WaitGroup{}

    for i := 0; i < 2; i++ {
        wg.Add(1)
        go process_subslice(quit,
            &wg,
            slice,
            i*4,     // this way slice is divided
            (1+i)*4, // in two subslices with indexes [0, 3] and [4,7]
            func() { time.Sleep(1 * time.Second) }) // pass empty func to test normal execution
    }

    wg.Add(1)
    go simulate_close_signal(quit, &wg)

    wg.Wait()

    fmt.Println("Processed slice: ", slice)

}

The Go Playground


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.