Lesson 4
Practice Project: Simple Multithreaded Application
Practice Project: Simple Multithreaded Application

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

Objective

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

  1. Creating a Downloader Class:

    • The Downloader class represents a task that downloads a file.
    • You will use threads to execute instances of this class concurrently, simulating asynchronous downloads.
  2. Simulating File Downloads with Delays:

    • To make the downloads feel realistic, we'll introduce delays using std::this_thread::sleep_for.
    • This will also help you understand how to manage and coordinate multiple threads working over time.
  3. Managing Multiple Threads:

    • You'll learn how to start multiple download threads and ensure they complete correctly.
    • Methods such as join() and detach() will be crucial here, ensuring that the main program waits for all downloads to finish before proceeding.

Here's a preview of what you'll be working towards:

C++
1#ifndef DOWNLOADER_H 2#define DOWNLOADER_H 3 4#include <iostream> 5#include <string> 6#include <thread> 7#include <chrono> 8#include <random> 9 10class Downloader { 11public: 12 Downloader(const std::string& fileName) : fileName_(fileName), rndEngine_(std::random_device{}()) {} 13 14 void operator()() { 15 try { 16 std::cout << "Downloading " << fileName_ << std::endl; 17 std::uniform_int_distribution<int> dist(100, 200); 18 std::this_thread::sleep_for(std::chrono::milliseconds(dist(rndEngine_))); 19 std::cout << "Completed " << fileName_ << std::endl; 20 } catch (...) { 21 std::cout << "Download interrupted for " << fileName_ << std::endl; 22 } 23 } 24 25private: 26 std::string fileName_; 27 std::mt19937 rndEngine_; 28}; 29 30#endif // DOWNLOADER_H 31 32int main() { 33 std::thread t1(Downloader("file1.txt")); 34 std::thread t2(Downloader("file2.txt")); 35 t1.join(); 36 t2.join(); 37 std::cout << "All downloads completed" << std::endl; 38 return 0; 39}

Let's break down the code snippet above:

  • The Downloader class represents a task that downloads a file. It takes the file name as a parameter and simulates a download operation.
    • The std::uniform_int_distribution object dist generates random delays between 100 and 200 milliseconds.
    • The std::this_thread::sleep_for function pauses the thread for the specified duration.
      • Note, that we use std::chrono::milliseconds to specify the duration in milliseconds and the rndEngine_ object is used to generate random numbers for the delay. We seed it with std::random_device{} to ensure different sequences each time.
    • The operator() function is the entry point for the thread, where the download operation is performed.
  • In the main function:
    • We create two threads t1 and t2, each executing an instance of the Downloader class with different file names.
    • We use the join() method to wait for both threads to complete before printing "All downloads completed".
Why It Matters

Understanding how to create and manage a multithreaded 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: Multithreading 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 multithreading knowledge to life.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.