C++ Multithreading Developer Interview Questions & Answers

4 avg. rating (80% score) - 1 votes

C++ Multithreading Developer Interview Questions & Answers

Are you preparing for C++ Multithreading Developer job interview? Need Some C++ Multithreading Developer interview question and answers to clear the interview and get your desired job in first attempt? Then we the Wisdomjobs have provided you with the complete details about the C++ Multithreading Developer on our site page. Multithreaded applications execute several threads in a single processor environment, letting developers achieve concurrency. If you are well familiar with the C++ Multithreading Developer topics then there are various leading companies that offer various job roles like C++ Developer – Multithreading, Video Codec Developer - C/C++, Software Engineer - Multithreading / C++ and many other roles too. To know more on C++ Multithreading Developer related topics and also for various C++ Multithreading Developer job roles visit our site Wisdomjobs C++ Multithreading Developer page.

C++ Multithreading Developer Interview Questions

C++ Multithreading Developer Interview Questions
    1. Question 1. What Header File Should You Include For Using C++11 Multithreading Capabilities?

      Answer :

      Use the <thread> header file

      #include <thread>

      Note: The thread functionality is defined in the "std" namespace.

    2. Question 2. What Are The Different Ways Of Creating A Thread In C++11?

      Answer :

      There are essentially four ways of creating a thread:

      • Create a thread with a function pointer
      • Create a thread with a function object
      • Create a thread with a lambda
      • Create a thread with a member function

    3. Question 3. How Can A C++11 Thread Be Created With A Function Pointer?

      Answer :

      Just pass in the address of a function to the thread constructor. The thread will start executing the function immediately.

      #include "stdafx.h"

      #include <thread>

      #include <iostream>

      using namespace std;

      void FireMissile()

      {

        cout << "Firing sidewinder missile " << endl;

      }

      int main()

      {

        //Creating a thread with a function pointer

        thread t1(FireMissile);

        t1.join();

        return 0;

      }

    4. Question 4. How Can A C++11 Thread Be Created With A Function Object?

      Answer :

      Create a function object "Missile" and pass it to the thread constructor.

      #include "stdafx.h"

      #include <thread>

      #include <iostream>

      using namespace std;

      //Create the function object

      class Missile

      {

      public:

        void operator() () const

        {

          cout << "Firing Tomahawk missile" << endl;

        }

      };

      int main()

      {

        //Creating a thread with an function object

        Missile tomahawk;

        thread t1(tomahawk);

        t1.join();

        return 0;

      }

    5. Question 5. How Can A C++11 Thread Be Created With A Lambda?

      Answer :

      #include "stdafx.h"

      #include <thread>

      #include <iostream>

      using namespace std;

      int main()

      {

        thread t1([] {

          cout << "Launching Scud missile" << endl;

        });

        t1.join();

        return 0;

      }

    6. Question 6. Can A Lambda Closure Be Used To Create A C++11 Thread?

      Answer :

      Yes ! A lambda closure is nothing but a variable storing a lambda expression. You can store a lambda in a closure if you intend to reuse the lambda expression at more than one place in your code.

      #include "stdafx.h"

      #include <thread>

      #include <iostream>

      using namespace std;

      int main()

      {

        // Define a lambda closure

        auto LaunchMissileFunc = []() -> void { cout << "Launching Cruiser Missile" << endl; };

        thread t1(LaunchMissileFunc);

        t1.join();

        return 0;

      }

    7. Question 7. How Can A C++11 Thread Be Created With A Member Function?

      Answer :

      #include "stdafx.h"

      #include <thread>

      #include <iostream>

      using namespace std;

      class Torpedo

      {

      public:

        void LaunchTorpedo()

        {

          cout << " Launching Torpedo" << endl;

        }

      };

      int main()

      {

        //Execute the LaunchTorpedo() method for a specific Torpedo object on a seperate thread

        Torpedo torpedo;

        thread t1(&Torpedo::LaunchTorpedo, &torpedo);

        t1.join();

        return 0;

      }

      Note that here you're executing the LaunchTorpedo() method for a specific Torpedo object on a seperate thread. If other threads are accessing the same "torpedo" object, you'll need to protect the shared resources of that object with a mutex.

    8. Question 8. What Does Joining C++11 Threads Mean? Alternatively What Does The Std::thread::join() Do?

      Answer :

      A call to std::thread::join() blocks until the thread on which join is called, has finished executing. In each of the examples above, the join() call ensures that the main method waits for the execution of the spawned threads to finish before it can exit the application.

      On the other hand, if we do not call join() after creating a thread in the above case, the main function will not wait for the spawned thread to complete before it tears down the application. If the application tears down before the spawned thread finishes, it will terminate the spawned thread as well, even if it has not finished executing. This can leave data in a very inconsistent state and should be avoided at all cost.

    9. Question 9. Can You Name A Situation Where Joining Threads Should Be Avoided?

      Answer :

      A call to join() blocks the caller thread. This is really bad in situations where the caller thread is a main UI thread – because if the UI thread blocks, the application will stop responding to user inputs which will make it seem hanged.

      Another place where calling join() is not advisable is inside a main game loop. Calling join() can block update and rendering of the game scene and severly impact the user experience (it'll be like watching a You tube video on a dial up internet connection !).

    10. Question 10. Can You Create A C++11 Thread With A Function Pointer That Takes A Bunch Of Arguments?

      Answer :

      Yes ! You can just pass the function arguments to the thread constructor. The thread constructor is a variadic template, which means it can accept any number of arguments. Here's an example:

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      using namespace std;

      void FireTorpedo(int numCities, string torpedoType)

      {

        cout << "Firing torpedo " << torpedoType << " at" << numCities << " cities." << endl;

      }

      int main()

      {

        thread t1(FireTorpedo, 3, "HungryShark");

        t1.join();

        return 0;

      }

    11. Question 11. Can You Create A C++11 Thread With A Lambda Closure That Takes A Bunch Of Arguments?

      Answer :

      Yes – just like the previous case, you can pass the arguments needed by the lambda closure to the thread constructor.

      auto LaunchTorpedoFunc = [](int numCities, string torpedoType) -> void { cout << "Firing torpedo " << torpedoType << " at" << numCities << " cities." << endl; };

      thread t1(LaunchTorpedoFunc, 7, "Barracuda");

      t1.join();

    12. Question 12. Are The Arguments Passed To A C++11 Thread's Constructor Pass By Vale Or Pass By Reference?

      Answer :

      Thread function arguments are always pass by value, i.e., they are always copied into the internal storage for threads. Any changes made by the thread to the arguments passed does not affect the original arguments. For example, we want the "targetCity" to be modified by the thread but it never happens:

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      #include <functional>

      using namespace std;

      void ChangeCurrentMissileTarget(string& targetCity)

      {

        targetCity = "Metropolis";

        cout << " Changing The Target City To " << targetCity << endl;

      }

      int main()

      {

        string targetCity = "Star City";

        thread t1(ChangeCurrentMissileTarget, targetCity);

        t1.join();

        cout << "Current Target City is " << targetCity << endl;

        return 0;

      }

      OUTPUT:

      Changing The Target City To Metropolis

      Current Target City is Star City

      Note that the "targetCity" variable is not modified.

    13. Question 13. How Can We Pass C++11 Thread Arguments By Reference?

      Answer :

      We need to use std::ref() from the <functional> header. Consider the following code snippet and associated output.

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      #include <functional>

      using namespace std;

      void ChangeCurrentMissileTarget(string& targetCity)

      {

        targetCity = "Metropolis";

        cout << " Changing The Target City To " << targetCity << endl;

      }

      int main()

      {

        string targetCity = "Star City";

        thread t1(ChangeCurrentMissileTarget, std::ref(targetCity));

        t1.join();

        cout << "Current Target City is " << targetCity << endl;

        return 0;

      }

      OUTPUT:

      Changing The Target City To Metropolis

      Current Target City is Metropolis

      Notice that the changes to "targetCity" made by the thread was preserved once the thread exited.

    14. Question 14. Does A C++11 Thread Act On A Specific Instance Of A Function Object?

      Answer :

      No – function objects are copied to the internal storage for the thread. If you need to execute the operation on a specific instance of the function object, you should use std::ref() from <functional> header to pass your function object by reference.

    15. Question 15. How Can You Create Background Tasks With C++11 Threads?

      Answer :

      You can make a std::thread run in the background by calling std::thread::detach() on it. Once detached, a thread continues to run in the background and cannot be communicated with or waited upon to complete. When you detach a thread, the ownership and control passes over to the C++ Runtime Library, which ensures that the resources allocated to the thread are deallocated once the thread exits.

      Here's a contrived example. We have a Count() function that prints numbers 1 to 1000 on the screen. If we create a thread to run the function and detach the thread immediately, we'll not see any output – because the main thread terminates before the "Count" thread has had an opportunity to run. To see some of the output, we can put the main thread to sleep for 10 miliseconds which gives the "count" thread to send some of the output to the screen.

      #include "stdafx.h"

      #include

      #include

      #include

      #include

      using namespace std;

      void Count()

      {

        for (int i = 0; i < 100; i++)

        {

          cout << "counter at: " << i << endl;

        }

      }

      int main()

      {

        thread t1(Count);

      std::this_thread::sleep_for(std::chrono::milliseconds(10));

        t1.detach();

        return 0;

      }

    16. Question 16. Can The Ownership Of C++11 Threads Be Transferred At Runtime?

      Answer :

      Yes. std::thread object owns a resource, where the resource is a current thread of execution. You can call std::move to move the ownership of the underlying resource from one std::thread object to another. The question is – why would you want to do that? Here's a scenario:You want to write a function that creates a thread but does not want to wait for it to finish. Instead it wants to pass the thread to another function which will wait for the thread to finish and execute some action once the execution is done.

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      #include <functional>

      using namespace std;

      void FireHTTPGet()

      {

      std::this_thread::sleep_for(std::chrono::milliseconds(5000));

        cout << "Finished Executing HTTP Get"<< endl;

      }

      void ProcessHTTPResult(thread t1)

      {

        t1.join();

        cout << "HTTP Get Thread Finished Executing - Processing Result Data!" << endl;

      }

      int main()

      {

        thread t11(FireHTTPGet);

        thread t12(ProcessHTTPResult, std::move(t11));

        //Do bunch of other processing without waiting for t11 to finish - instead now we've shouldered off the 

        // responsibility of monitoring t11 thread to t12.

        //Finally wait for t12 to finish

        t12.join();

        return 0;

      }

      OUTPUT:

      Finished Executing HTTP Get

      HTTP Get Thread Finished Executing - Processing Result Data!

    17. Question 17. What Is C++11 Thread Local Storage (thread_local)?

      Answer :

      A thread_local object comes into existence when a thread starts and is destroyed when the thread ends. Each thread has its own instance of a thread-Local object.

      To fully understand the implications, let's look at an example- here we'll declare a global variable "globalvar" as thread_local. This'll give each thread it's own copy of globalVar and any modifications made to globalVar will only persist inside that particular thread.In the example below, each of the two threads are modifying globalVar – but they are not seeing each other's change, neither is the main thread.

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      #include <functional>

      #include <mutex>

      using namespace std;

      thread_local int globalVar = 0;

      mutex mu;

      void PrettyPrint(int valueToPrint)

      {

        lock_guard<mutex> lock(mu);

        cout << "Value of globalVar in thread " << this_thread::get_id() << " is " << globalVar << endl;

      }

      void thread_Local_Test_Func(int newVal)

      {

        globalVar = newVal;

        PrettyPrint(globalVar);

      }

      int main()

      {

        globalVar = 1;

        thread t1(thread_Local_Test_Func, 5);

        thread t2(thread_Local_Test_Func, 20);

        t1.join();

        t2.join();

        cout << "Value of globalVar in MAIN thread is " << globalVar << endl;

          return 0;

      }

      Here's the output of the program – you can see that the three threads (t1, t2 and MAIN) does not see each other's changes to globalVar.

      Value of globalVar in thread 17852 is 5

      Value of globalVar in thread 29792 is 20

      Value of globalVar in MAIN thread is 1

      Can you guess what the output will be if globalVar was not declared thread_local ? Here it is :

      Value of globalVar in thread 27200 is 5

      Value of globalVar in thread 31312 is 20

      Value of globalVar in MAIN thread is 20

      If the global value was not thread local, the change made by each thread will be persisted outside the thread – here the MAIN thread is feeling the effect  of the change made by t2 and hence printing "20" instead of "1".

    18. Question 18. How Can You Retrieve Results From A Thread?

      Answer :

      As we'll see in a subsequent tutorial, the easiest and recommended way is to use "futures". However, you can still get the result of some calculation from a thread by either:

      Passing reference to a result variable to the thread in which the thread stores the results

      Store the result inside a class memeber variable of a function object which can be retrieved once the thread has finished executing.

    19. Question 19. What Is "oversubscription"?

      Answer :

      Oversubscription is a situation where more threads are vying for runtime than the underlying hardware can support. One of the biggest cost associated with multiple threads is that of context-switches that happens when the processor switches threads. Ideally, the you'd not want to create more threads than the hardware can support.

    20. Question 20. How Can I Avoid "oversubscription" In C++11 When Working With Multiple Threads?

      Answer :

      C++11 provides a way to get a hint at the number of threads that can be run in parallel from an application – which most of the time coincides with the number of logical cores.

      unsigned int n = std::thread::hardware_concurrency();

      On my system with 12 logical cores, it returns 12. This means that I should not attempt to fork more than 12 threads in my application. Note that this is VC++ – other C++ compiler implementations might give different results

    21. Question 21. How Can You Identify Different C++11 Threads?

      Answer :

      C++11 gives unique ids to forked threads which can be retrieved using :

      By calling the get_id() member function for a specific thread

      By calling std::this_thread::get_id() for the currently executing thread

      An example of both is given below:

      #include "stdafx.h"

      #include <string>

      #include <thread>

      #include <iostream>

      #include <functional>

      using namespace std;

      void Count()

      {

        for (int i = 0; i < 100; i++)

        {

          cout << "counter at: " << i << endl;

        }

      }

      int main()

      {

      thread t22(Count);

        //Get the ID of the t22 thread

        std::thread::id k = t22.get_id();

        cout << k << endl;

        //Get the ID of the MAIN Thread

        std::thread::id j = std::this_thread::get_id();

        cout << j << endl;

        return 0;

      }

      If I run this code, I can see the thread ids in "threads" and "locals" window. Also note that the thread name is almost useless.

      However, the "Location" column can give an indication as to which thread is executing.

C++ Tutorial

C++ Multithreading Developer Interview Questions

C++ Multithreading Developer Practice Tests

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

C++ Tutorial