Basic use of C + + Standard Thread Library

Posted by ambrennan on Sun, 06 Feb 2022 03:14:40 +0100

Qt has more thread classes with high encapsulation. It is found that the thread library in the C + + standard library is a little rusty. Here is a summary of the thread related content in the C + + standard library for your reference. In fact, the standard C + + thread library is also very useful.

1. Create thread to execute asynchronously

We can create a thread directly and asynchronously through async function. This method is relatively simple. The result of thread execution can be obtained directly with future < T >.

#include <iostream>
#include <future>

//Function corresponding to thread
bool thread_func(int x) {
	return true;
}
int main()
{
	int inputNum = 65547;
	std::future<bool> future = std::async(thread_func, inputNum);
	bool ret = future.get();
	getchar();
}

2. Prevent thread conflicts by using mutexes

Generally, there is no thread safety problem when reading content synchronously between threads, but conflicts are easy to occur if threads write the same content synchronously. For example, if each thread executes once, the global execution times will be accumulated once. If multiple threads execute operations at the same time and do not lock when writing, it may lead to the repeated accumulation of execution times.

#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; 

int count=0;

void print_block(int n) {
	mtx.lock();
   count++;
	//do somethings
	mtx.unlock();
}
int main()
{
	std::thread thread1(print_block, 50);
	std::thread thread2(print_block, 50);
 
	thread1.join();
	thread2.join();
	getchar();
	return 0;
}

3. Use semaphores to control the operation of threads

The condition_variable is used to control the running of the thread. When the thread starts, if the condition variable waits, it will block the running of the thread. The thread can not start running until the condition variable sends the corresponding notification. By using conditional variables, we can control the operation of threads and avoid the consumption of computing resources when threads run empty.

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;

void print_id(int id) {
	std::unique_lock<std::mutex> lck(mtx);
	cv.wait(lck);
	std::cout << "thread " << id << '\n';
}
void go() {
	std::unique_lock<std::mutex> lck(mtx);
	cv.notify_all();
}
int main()
{
	std::thread threads[10];
	for (int i = 0; i < 10; ++i)
		threads[i] = std::thread(print_id, i);
   std::cout << "start thread run" << std::endl;
	go();
	for (auto& th : threads){th.join();}
	getchar();
	return 0;
}

4. Realize inter process communication through promise

In many cases, there is a sequence of execution between threads. We need to wait for the execution of the previous thread to get the result before executing the current thread. At this time, it involves inter thread waiting and data transmission. At this time, STD:: promise < T > can be used. By using this variable, we can easily realize inter thread waiting and data transmission.

#include <iostream>
#include <future>
#include <chrono>
void Thread_Fun1(std::promise<int> &p)
{
	std::this_thread::sleep_for(std::chrono::seconds(5));
	int iVal = 233;
	std::cout << "incoming data (int): " << iVal << std::endl;
	p.set_value(iVal);
}

void Thread_Fun2(std::future<int> &f)
{
	//Block the function until the data passed in by the associated std::promise object is received
	auto iVal = f.get();
	std::cout << "Data received(int): " << iVal << std::endl;
}

int main()
{
	std::promise<int> pr1;
	std::future<int> fu1 = pr1.get_future();

	std::thread t1(Thread_Fun1, std::ref(pr1));
	std::thread t2(Thread_Fun2, std::ref(fu1));

	//Block to end of thread
	t1.join();
	t2.join();
	return 1;
}

Topics: C++ Back-end