C++11: How to create Vector of Thread Objects ?

In this article we will create a vector thread and discuss things which we need to take care while using it.

Creating & Using vector of std::thread

Let’s Create a vector of std::thread objects i.e.

// Create a vector of threads
std::vector<std::thread> vecOfThreads;

Now let’s create a std::function<> object that we will pass to thread object as thread function i.e.

// Create a function object
std::function<void()> func = []() {
					//Do Some Important Work
					// .....
					//Print Thread ID
					std::cout << "From Thread ID : "<<std::this_thread::get_id() << "\n";
					};

Now let’s create 2 thread objects using this std::function objects i.e.

std::thread th1(func);
std::thread th2(func);

Now, as std::thread objects are move only i.e. we can not copy them, only move them. Therefore, we need to move these 2 thread objects in vector i.e.

// Move thread objects to vector
vecOfThreads.push_back(std::move(th1));
vecOfThreads.push_back(std::move(th2));

We can also push std::thread without specifically specifying std::move(), if we pass them as rvalue i.e.

// Add a Thread object to vector
vecOfThreads.push_back(std::thread(func));

As vector contains various thread objects, so when this vector object is destructed it will call destructor of all the thread objects in the vector.
If any of the destructed thread object is joinable and not joined then std::terminate() will be called from its destructor. Therefore its necessary to join all the joinable threads in vector before vector is destructed i.e.

// Iterate over the thread vector
for (std::thread & th : vecOfThreads)
{
	// If thread Object is Joinable then Join that thread.
	if (th.joinable())
		th.join();
}

Complete example is as follows,

#include <thread>
#include <vector>
#include <iostream>


int main()
{
	// Create a vector of threads
	std::vector<std::thread> vecOfThreads;

// Create a function object
std::function<void()> func = []() {
					//Do Some Important Work
					// .....
					//Print Thread ID
					std::cout << "From Thread ID : "<<std::this_thread::get_id() << "\n";
					};

	// Add a Thread object to vector
	vecOfThreads.push_back(std::thread(func));


	// Create 3 differet thread objects
	std::thread th1(func);
	std::thread th2(func);
	std::thread th3(func);

	// Move all three thread objects to vector
	vecOfThreads.push_back(std::move(th1));
	vecOfThreads.push_back(std::move(th2));
	vecOfThreads.push_back(std::move(th3));

	// Do some important work in main thread.

	/** Wait for all the threads in vector to join **/

	// Iterate over the thread vector
	for (std::thread & th : vecOfThreads)
	{
		// If thread Object is Joinable then Join that thread.
		if (th.joinable())
			th.join();
	}

	return 0;
}

Output:

From Thread ID : 140261435352832
From Thread ID : 140261452138240
From Thread ID : 140261426960128
From Thread ID : 140261443745536

To compile the above example in linux use,

g++ –std=C++11 example.cpp -lpthread

Use vector<std::thread> cautiously

std::vector<std::thread> vecOfThreads;

Move only vector of thread

As thread objects are move only objects, therefore we can not copy vector of thread objects to an another of vector of thread i.e.

// Can not copy vector of thread , COMPILE TIME ERROR
std::vector<std::thread> newVecThreads = vecOfThreads;

It will not compile

Therefore, we can only move vector of thread to an another vector thread i.e.

// Can Only move vector of thread
std::vector<std::thread> newVecThreads = std::move(vecOfThreads);

Changing contents of vector of thread

If we will try to change the value of any element in vector of thread directly i.e.

//Destructor of already existing thread object will call terminate
vecOfThreads[1] = std::move(th4);

It will crash our application, because on replacing a thread object inside the vector, destructor of existing thread object will be called and we haven’t joined that object yet. So, it call terminate in its destructor. So, to replace a thread object in vector, we first need to join the existing object and then replace it with new one i.e.

// First join the existing object
if(vecOfThreads[1].joinable())
	vecOfThreads[1].join();

// Replace the joined thread object
vecOfThreads[1] = std::move(th4);

Complete example is as follows,

#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <chrono>
int main()
{
	// Create a vector of threads
	std::vector<std::thread> vecOfThreads;

	// Create a function object
	std::function < void() > func = []() {
			//Do Some Important Work
			// Sleep for 1 second
				std::this_thread::sleep_for (std::chrono::seconds(1));
			//Print Thread ID
				std::cout << "From Thread ID : "<<std::this_thread::get_id() << "\n";
			};

	// Add a Thread object to vector
	vecOfThreads.push_back(std::thread(func));

	// Create 3 differet thread objects
	std::thread th1(func);
	std::thread th2(func);
	std::thread th3(func);

	// Move all three thread objects to vector
	vecOfThreads.push_back(std::move(th1));
	vecOfThreads.push_back(std::move(th2));
	vecOfThreads.push_back(std::move(th3));

	std::thread th4(func);

	//Destructor of already existing thread object will call terminate
	//vecOfThreads[1] = std::move(th4);

	// First join the existing object
	if (vecOfThreads[1].joinable())
		vecOfThreads[1].join();

	// Replace the joined thread object
	vecOfThreads[1] = std::move(th4);

	// Can not copy vector of thread , COMPILE TIME ERROR
	//std::vector<std::thread> newVecThreads = vecOfThreads;

	// Can Only move vector of thread
	std::vector<std::thread> newVecThreads = std::move(vecOfThreads);

	/** Wait for all the threads in vector to join **/

	// Iterate over the thread vector
	for (std::thread & th : newVecThreads)
	{
		// If thread Object is Joinable then Join that thread.
		if (th.joinable())
			th.join();
	}

	return 0;
}

Output:

From Thread ID : 140642994353920
From Thread ID : 140643002746624
From Thread ID : 140642985961216
From Thread ID : 140643011139328
From Thread ID : 140642977568512

To compile the above example in linux use,

g++ –std=C++11 example.cpp -lpthread

 

2 thoughts on “C++11: How to create Vector of Thread Objects ?”

  1. Thanks for this tutorial, it’s the first tutorial I could find that resolved my issue. What i was missing was the std::move() function and I wasn’t able to find it for months now.

Leave a Comment

Your email address will not be published. Required fields are marked *

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

Scroll to Top