In this article we will discuss how to stop or terminate a thread in C++11.

C++11 does not provides a direct method to stop a running thread and that’s because that thread might have some resources to release or close before exit i.e.

  • What if a thread has acquired a lock and we kill that thread suddenly, then who’s gonna release that lock ?
  • What if a thread has opened a file to write the text and we stopped that thread, then who’s gonna close that file ?
  • What if thread has allocated memory on heap and before it could delete that memory, we stopped the thread. Then who’s gonna prevent that memory leak.

Therefore there is no direct function to close the thread. But we can notify the thread to exit and we can implement out thread in a such a way that after some interval or at some checkpoints it should check, if I am requested to exit or not. If yes then it should exit gracefully , by releasing all the resources.

Stopping a Thread using std::future<>

We can pass a std::future<void> object to thread and thread should exit when value in future is available. As, we want to only signal the thread and not actually passing any value in that signal, so we will can use future object of type void.

Let’s create a promise object of type void in main function i.e.

// Create a std::promise object
std::promise<void> exitSignal;

Now, fetch the associated future object from this promise in main function i.e.
//Fetch std::future object associated with promise
std::future<void> futureObj = exitSignal.get_future();

Now in main function while creating the thread, pass the future object to the thread function i.e.
// Starting Thread & move the future object in lambda function by reference
std::thread th(&threadFunction, std::move(futureObj));

Inside the thread, we are doing some Work and keep on checking that if thread has been requested to exit i.e. value in future is available or not.
void threadFunction(std::future<void> futureObj)
{
	std::cout << "Thread Start" << std::endl;
	while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout)
	{
		std::cout << "Doing Some Work" << std::endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(1000));

	}
	std::cout << "Thread End" << std::endl;

}

As soon as we set value in promise object from main function, value in future object will available in thread function i.e.
//Set the value in promise
exitSignal.set_value();

Complete example is as follows,
#include <thread>
#include <iostream>
#include <assert.h>
#include <chrono>
#include <future>

void threadFunction(std::future<void> futureObj)
{
	std::cout << "Thread Start" << std::endl;
	while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout)
	{
		std::cout << "Doing Some Work" << std::endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(1000));

	}
	std::cout << "Thread End" << std::endl;

}
int main()
{

	// Create a std::promise object
	std::promise<void> exitSignal;

	//Fetch std::future object associated with promise
	std::future<void> futureObj = exitSignal.get_future();

	// Starting Thread & move the future object in lambda function by reference
	std::thread th(&threadFunction, std::move(futureObj));

	//Wait for 10 sec
	std::this_thread::sleep_for(std::chrono::seconds(10));

	std::cout << "Asking Thread to Stop" << std::endl;

	//Set the value in promise
	exitSignal.set_value();

	//Wait for thread to join
	th.join();

	std::cout << "Exiting Main Function" << std::endl;
	return 0;
}

Output:
Thread Start
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Asking Thread to Stop
Thread End
Exiting Main Function

Creating a Stoppable Task

Creating promise and future object every time, when we want to create task that can be stopped, is a repeating task.
Let’s avoid that by creating a Stoppable class that provide all this functionality in object oriented manner.

Stoppable class that encapsulate the promise and future object

/*
 * Class that encapsulates promise and future object and
 * provides API to set exit signal for the thread
 */
class Stoppable
{
	std::promise<void> exitSignal;
	std::future<void> futureObj;
public:
	Stoppable() :
			futureObj(exitSignal.get_future())
	{

	}
	Stoppable(Stoppable && obj) : exitSignal(std::move(obj.exitSignal)), futureObj(std::move(obj.futureObj))
	{
		std::cout << "Move Constructor is called" << std::endl;
	}
	Stoppable & operator=(Stoppable && obj)
	{
		std::cout << "Move Assignment is called" << std::endl;
		exitSignal = std::move(obj.exitSignal);
		futureObj = std::move(obj.futureObj);
		return *this;
	}

	// Task need to provide defination  for this function
	// It will be called by thread function
	virtual void run() = 0;


	// Thread function to be executed by thread
	void operator()()
	{
		run();
	}

	//Checks if thread is requested to stop
	bool stopRequested()
	{
		// checks if value in future object is available
		if (futureObj.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout)
			return false;
		return true;
	}
	// Request the thread to stop by setting value in promise object
	void stop()
	{
		exitSignal.set_value();
	}
};

We just need to extend this class in our task class and provide definition for run() function, which will like our thread function i.e.
/*
 * A Task class that extends the Stoppable Task
 */
class MyTask: public Stoppable
{
public:
	// Function to be executed by thread function
	void run()
	{
		std::cout << "Task Start" << std::endl;

		// Check if thread is requested to stop ?
		while (stopRequested() == false)
		{
			std::cout << "Doing Some Work" << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));

		}
		std::cout << "Task End" << std::endl;
	}
};

Now lets see how to use this Stoppable task in main function i.e.
// Creating our Task
MyTask task;

//Creating a thread to execute our task
std::thread th([&]()
{
	task.run();
});

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

std::cout << "Asking Task to Stop" << std::endl;
// Stop the Task
task.stop();

//Waiting for thread to join
th.join();

Learn more about multithreading in C++11 / 14

Complete example is as follows,

#include <thread>
#include <iostream>
#include <assert.h>
#include <chrono>
#include <future>

/*
 * Class that encapsulates promise and future object and
 * provides API to set exit signal for the thread
 */
class Stoppable
{
	std::promise<void> exitSignal;
	std::future<void> futureObj;
public:
	Stoppable() :
			futureObj(exitSignal.get_future())
	{

	}
	Stoppable(Stoppable && obj) : exitSignal(std::move(obj.exitSignal)), futureObj(std::move(obj.futureObj))
	{
		std::cout << "Move Constructor is called" << std::endl;
	}

	Stoppable & operator=(Stoppable && obj)
	{
		std::cout << "Move Assignment is called" << std::endl;
		exitSignal = std::move(obj.exitSignal);
		futureObj = std::move(obj.futureObj);
		return *this;
	}

	// Task need to provide defination  for this function
	// It will be called by thread function
	virtual void run() = 0;


	// Thread function to be executed by thread
	void operator()()
	{
		run();
	}

	//Checks if thread is requested to stop
	bool stopRequested()
	{
		// checks if value in future object is available
		if (futureObj.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout)
			return false;
		return true;
	}
	// Request the thread to stop by setting value in promise object
	void stop()
	{
		exitSignal.set_value();
	}
};

/*
 * A Task class that extends the Stoppable Task
 */
class MyTask: public Stoppable
{
public:
	// Function to be executed by thread function
	void run()
	{
		std::cout << "Task Start" << std::endl;

		// Check if thread is requested to stop ?
		while (stopRequested() == false)
		{
			std::cout << "Doing Some Work" << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));

		}
		std::cout << "Task End" << std::endl;
	}
};

int main()
{
	// Creating our Task
	MyTask task;

	//Creating a thread to execute our task
	std::thread th([&]()
	{
		task.run();
	});

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

	std::cout << "Asking Task to Stop" << std::endl;
	// Stop the Task
	task.stop();

	//Waiting for thread to join
	th.join();
	std::cout << "Thread Joined" << std::endl;
	std::cout << "Exiting Main Function" << std::endl;
	return 0;
}

Output:
Task Start
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Asking Task to Stop
Task End
Thread Joined
Exiting Main Function

 

 

Join a list of 2000+ Programmers for latest Tips & Tutorials