Simple Concurrent Application

Practice Project: Simple Concurrent Application

Welcome! Through our recent lessons, you've gained a strong foundation in creating and managing goroutines, as well as understanding data sharing between goroutines using synchronization primitives. Now, it's time to put all that knowledge into practice by building a simple concurrent application.

Objective

In this project, you will create a basic program that simulates downloading files concurrently. This will involve:

  1. Creating a Downloader function.

    • The Downloader function represents a task that downloads a file.
    • You will use goroutines to execute this function concurrently, simulating asynchronous downloads.
  2. Simulating file downloads with delays.

    • To make the downloads feel realistic, we will introduce delays using time.Sleep.
    • This will also help you understand how to manage and coordinate multiple goroutines as they work over time.
  3. Managing multiple goroutines.

    • You will learn how to start multiple download goroutines and ensure they complete correctly.
    • You will use sync.WaitGroup to synchronize goroutines, ensuring that the main program waits for all downloads to finish before proceeding.

Here is a preview of what you will be working toward:

package main

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

func downloader(fileName string, wg *sync.WaitGroup) {
    defer wg.Done()
    
    fmt.Printf("Downloading %s\n", fileName)
    
    // Generate random delay between 100 and 200 milliseconds
    delay := 100 + rand.Intn(101)
    time.Sleep(time.Duration(delay) * time.Millisecond)
    
    fmt.Printf("Completed %s\n", fileName)
}

func main() {
    rand.Seed(time.Now().UnixNano())
    
    var wg sync.WaitGroup
    
    wg.Add(2)
    go downloader("file1.txt", &wg)
    go downloader("file2.txt", &wg)
    
    wg.Wait()
    fmt.Println("All downloads completed")
}

Let's break down the code snippet above:

  • The downloader function represents a task that downloads a file. It takes the fileName and a pointer to a WaitGroup as parameters and simulates a download operation.
    • The defer wg.Done() statement ensures that the WaitGroup counter is decremented when the function completes, regardless of how it exits.
    • rand.Intn(101) generates a random number between 0 and 100, which we add to 100 to get a delay between 100 and 200 milliseconds.
    • The time.Sleep function pauses the goroutine for the specified duration.
      • We use time.Duration(delay) * time.Millisecond to convert the integer delay into a proper time duration.
  • In the main function:
    • We seed the random number generator with rand.Seed(time.Now().UnixNano()) to ensure different sequences each time the program runs.
    • We create a WaitGroup to synchronize our goroutines.
    • We call wg.Add(2) to indicate that we will be waiting for two goroutines to complete.
    • We launch two goroutines using the go keyword, each executing the downloader function with a different file name.
    • We use wg.Wait() to block until both goroutines have called wg.Done(), ensuring that all downloads complete before printing "All downloads completed".

Why It Matters

Understanding how to create and manage a concurrent application is crucial for several reasons:

  • Real-World Applications: Many real-world applications require handling multiple tasks simultaneously, such as web servers managing multiple requests or programs performing background downloads.
  • Efficiency: Concurrency can significantly improve the efficiency of your programs by allowing tasks to run concurrently, making better use of system resources.
  • Skill Enhancement: Mastering these concepts will enhance your programming skills and make you proficient in handling complex concurrency issues.

Ready to take your skills to the next level? Let's dive into the practice project and bring your concurrency knowledge to life.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal