YouTube Icon

Interview Questions.

Top 21 C++ Multithreading Developer Interview Questions - Jul 25, 2022

fluid

Top 21 C++ Multithreading Developer Interview Questions

Q1. How Can You Retrieve Results From A Thread?

As we will see in a next academic, the easiest and encouraged manner is to apply "futures". However, you could still get the result of some calculation from a thread by either:

Passing reference to a end result variable to the thread wherein the thread shops the outcomes

Store the end result inside a class memeber variable of a characteristic object which may be retrieved once the thread has completed executing.

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

A thread_local item comes into lifestyles when a thread begins and is destroyed when the thread ends. Each thread has its personal example of a thread-Local item.

To fully understand the consequences, allow's observe an example- here we'll claim a worldwide variable "globalvar" as thread_local. This'll supply each thread it's very own copy of globalVar and any modifications made to globalVar will most effective persist interior that precise thread.In the instance below, each of the two threads are modifying globalVar – however they may be now not seeing each other's exchange, neither is the main thread.

#include "stdafx.H"

#encompass <string>

#consist of <thread>

#encompass <iostream>

#consist of <functional>

#consist of <mutex>

using namespace std;

thread_local int globalVar = zero;

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 essential()

  globalVar = 1;

  thread t1(thread_Local_Test_Func, five);

  thread t2(thread_Local_Test_Func, 20);

  t1.Join();

  t2.Be part of();

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

    return zero;

Here's the output of the program – you may see that the 3 threads (t1, t2 and MAIN) does no longer see every different'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 could be if globalVar turned into 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 worldwide cost changed into no longer thread neighborhood, the trade made by using each thread could be continued out of doors the thread – right here the MAIN thread is feeling the impact  of the exchange made by using t2 and subsequently printing "20" rather than "1".

Q3. How Can You Identify Different C++eleven Threads?

C++11 offers specific ids to forked threads which can be retrieved the use of :

By calling the get_id() member feature for a particular thread

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

An example of each is given beneath:

#consist of "stdafx.H"

#include <string>

#include <thread>

#encompass <iostream>

#consist of <functional>

the use of namespace std;

void Count()

  for (int i = 0; i < a hundred; i++)

  

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

  

int foremost()

thread t22(Count);

  //Get the ID of the t22 thread

  std::thread::id okay = 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 zero;

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

However, the "Location" column can deliver an illustration as to which thread is executing.

Q4. What Are The Different Ways Of Creating A Thread In C++eleven?

There are basically 4 approaches of creating a thread:

Create a thread with a characteristic pointer

Create a thread with a feature item

Create a thread with a lambda

Create a thread with a member feature

Q5. How Can A C++eleven Thread Be Created With A Lambda?

#include "stdafx.H"

#encompass <thread>

#encompass <iostream>

the use of namespace std;

int predominant()

  thread t1([] 

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

  );

  t1.Be a part of();

  go back zero;

Q6. What Does Joining C++eleven Threads Mean? Alternatively What Does The Std::thread::be a part of() Do?

A call to std::thread::be a part of() blocks until the thread on which be a part of is called, has completed executing. In every of the examples above, the be part of() call ensures that the primary technique waits for the execution of the spawned threads to complete before it can exit the utility.

On the other hand, if we do now not name join() after creating a thread in the above case, the main characteristic will no longer look ahead to the spawned thread to finish before it tears down the application. If the application tears down earlier than the spawned thread finishes, it will terminate the spawned thread as properly, even though it has not completed executing. This can leave information in a totally inconsistent kingdom and ought to be averted at all fee.

Q7. How Can I Avoid "oversubscription" In C++eleven When Working With Multiple Threads?

C++11 presents a way to get a touch at the wide variety 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 device with 12 logical cores, it returns @This me that I need to no longer attempt to fork more than 12 threads in my utility. Note that that is VC++ – different C++ compiler implementations may give distinct results

Q8. Can You Create A C++eleven Thread With A Function Pointer That Takes A Bunch Of Arguments?

Yes ! You can simply pass the function arguments to the thread constructor. The thread constructor is a variadic template, which me it can accept any quantity of arguments. Here's an instance:

#encompass "stdafx.H"

#consist of <string>

#include <thread>

#include <iostream>

using namespace std;

void FireTorpedo(int numCities, string torpedoType)

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

int important()

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

  t1.Be part of();

  go back zero;

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

No – characteristic items are copied to the inner storage for the thread. If you want to execute the operation on a particular instance of the function object, you should use std::ref() from <functional> header to bypass your characteristic item by using reference.

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

Just pass inside the cope with of a characteristic to the thread constructor. The thread will start executing the feature at once.

#encompass "stdafx.H"

#include <thread>

#include <iostream>

using namespace std;

void FireMissile()

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

int important()

  //Creating a thread with a characteristic pointer

  thread t1(FireMissile);

  t1.Be a part of();

  go back zero;

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

We want to use std::ref() from the <functional> header. Consider the subsequent code snippet and related output.

#consist of "stdafx.H"

#include <string>

#include <thread>

#include <iostream>

#include <functional>

the use of namespace std;

void ChangeCurrentMissileTarget(string& targetCity)

  targetCity = "Metropolis";

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

int principal()

  string targetCity = "Star City";

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

  t1.Be a part of();

  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.

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

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.Be part of();

Q13. What Header File Should You Include For Using C++11 Multithreading Capabilities?

Use the <thread> header document

#consist of <thread>

Note: The thread capability is defined inside the "std" namespace.

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

#encompass "stdafx.H"

#encompass <thread>

#include <iostream>

the usage of namespace std;

elegance Torpedo

public:

  void LaunchTorpedo()

  

    cout << " Launching Torpedo" << endl;

  

;

int predominant()

  //Execute the LaunchTorpedo() approach for a selected Torpedo item on a seperate thread

  Torpedo torpedo;

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

  t1.Join();

  go back zero;

Note that right here you are executing the LaunchTorpedo() approach for a selected Torpedo item on a seperate thread. If different threads are gaining access to the equal "torpedo" object, you will need to protect the shared assets of that item with a mutex.

Q15. What Is "oversubscription"?

Oversubscription is a scenario in which more threads are vying for runtime than the underlying hardware can guide. One of the most important cost related to a couple of threads is that of context-switches that takes place when the processor switches threads. Ideally, the you'll now not want to create more threads than the hardware can help.

Q16. How Can A C++eleven Thread Be Created With A Function Object?

Create a feature item "Missile" and pass it to the thread constructor.

#consist of "stdafx.H"

#encompass <thread>

#consist of <iostream>

using namespace std;

//Create the feature object

elegance Missile

public:

  void operator() () const

  

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

  

;

int major()

  //Creating a thread with an feature item

  Missile tomahawk;

  thread t1(tomahawk);

  t1.Join();

  return 0;

Q17. Can The Ownership Of C++11 Threads Be Trferred At Runtime?

Yes. Std::thread object owns a useful resource, in which the resource is a cutting-edge thread of execution. You can name std::circulate to transport the ownership of the underlying resource from one std::thread item to every other. The question is – why might you want to do this? Here's a scenario:You need to jot down a feature that creates a thread but does not want to watch for it to complete. Instead it wants to pass the thread to another feature if you want to anticipate the thread to complete and execute some movement once the execution is performed.

#consist of "stdafx.H"

#consist of <string>

#consist of <thread>

#consist of <iostream>

#encompass <functional>

the usage of namespace std;

void FireHTTPGet()

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

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

void ProcessHTTPResult(thread t1)

  t1.Be a part of();

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

int fundamental()

  thread t11(FireHTTPGet);

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

  //Do bunch of other processing without looking ahead to t11 to finish - alternatively now we have shouldered off the 

  // responsibility of tracking t11 thread to t12.

  //Finally watch for t12 to complete

  t12.Join();

  return zero;

OUTPUT:

Finished Executing HTTP Get

HTTP Get Thread Finished Executing - Processing Result Data!

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

A call to sign up for() blocks the caller thread. This is clearly horrific in situations wherein the caller thread is a first-rate UI thread – because if the UI thread blocks, the software will stop responding to user inputs so that it will make it seem hanged.

Another place wherein calling join() is not recommended is interior a first-rate recreation loop. Calling be a part of() can block update and rendering of the sport scene and severly effect the user enjoy (it will likely be like watching a You tube video on a dial up net connection !).

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

You can make a std::thread run within the heritage by means of calling std::thread::detach() on it. Once indifferent, a thread maintains to run inside the historical past and can't be communicated with or waited upon to finish. When you detach a thread, the ownership and control passes over to the C++ Runtime Library, which ensures that the assets allotted to the thread are deallocated as soon as the thread exits.

Here's a contrived instance. We have a Count() feature that prints numbers 1 to one thousand at the screen. If we create a thread to run the characteristic and detach the thread immediately, we're going to no longer see any output – due to the fact the main thread terminates before the "Count" thread has had an opportunity to run. To see some of the output, we are able to placed the main thread to sleep for 10 miliseconds which gives the "rely" thread to send some of the output to the display.

#encompass "stdafx.H"

#consist of

#include

#include

#consist of

the usage of namespace std;

void Count()

  for (int i = zero; i < one hundred; i++)

  

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

  

int main()

  thread t1(Count);

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

  t1.Detach();

  return zero;

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

Yes ! A lambda closure is nothing however a variable storing a lambda expression. You can save a lambda in a closure if you intend to reuse the lambda expression at multiple location for your code.

#encompass "stdafx.H"

#include <thread>

#include <iostream>

using namespace std;

int fundamental()

  // Define a lambda closure

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

  thread t1(LaunchMissileFunc);

  t1.Join();

  go back 0;

Q21. Are The Arguments Passed To A C++eleven Thread's Constructor Pass By Vale Or Pass By Reference?

Thread function arguments are constantly pass through price, i.E., they're constantly copied into the inner garage for threads. Any adjustments made by way of the thread to the arguments surpassed does no longer affect the unique arguments. For instance, we need the "targetCity" to be changed through the thread however it by no means occurs:

#encompass "stdafx.H"

#consist of <string>

#encompass <thread>

#include <iostream>

#encompass <functional>

the usage of namespace std;

void ChangeCurrentMissileTarget(string& targetCity)

  targetCity = "Metropolis";

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

int important()

  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 isn't modified.




CFG