欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++中标准线程库的基本使用介绍

程序员文章站 2022-06-15 16:09:52
目录1.创建线程异步执行2.通过使用互斥锁防止线程冲突3.采用信号量控制线程的运行4.通过promise实现进程间通信总结qt的封装程度比较高的线程类用多了,发现c++标准库里面的线程库有些生疏。这里...

qt的封装程度比较高的线程类用多了,发现c++标准库里面的线程库有些生疏。这里总结一下c++标准库里面的线程相关内容,供大家参考使用。其实标准c++的线程库也是挺好用的。

1.创建线程异步执行

我们可以通过async函数直接异步创建一个线程,这种方法相对来说比较简单,线程执行的结果可以直接用future<t>来进行获取。

#include <iostream>
#include <future>
 
//线程对应的函数
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.通过使用互斥锁防止线程冲突

线程间同步读取内容的话一般不会出现线程安全问题,但如果线程间同步写同一个内容的话就容易出现冲突。比如每个线程执行一次,就会给全局执行次数累加一次,如果多个线程同时执行操作,在写的时候没有加锁,这就有可能导致执行次数被重复累加的情况。

#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.采用信号量控制线程的运行

条件变量(condition_variable)用来控制线程的运行,线程启动的时候如果条件变量等待,会阻塞线程的运行,直到条件变量发送对应的通知线程才能开始运行。通过采用条件变量我们可以控制线程的运行,避免线程空运行消耗计算资源。

#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.通过promise实现进程间通信

很多时候线程间执行是有先后顺序的,我们需要等待上一个线程执行结束拿到结果之后再执行当前线程,这时候就涉及到线程间的等待和数据传递这时候std::promise<t>就能排上用场了,通过使用该变量我们可以很轻松的实现线程间的等待和数据传递。

#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 << "传入数据(int):" << ival << std::endl;
	p.set_value(ival);
}
 
void thread_fun2(std::future<int> &f)
{
	//阻塞函数,直到收到相关联的std::promise对象传入的数据
	auto ival = f.get();
	std::cout << "收到数据(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));
 
	//阻塞至线程结束
	t1.join();
	t2.join();
	return 1;
}

总结

到此这篇关于c++中标准线程库的基本使用介绍的文章就介绍到这了,更多相关c++标准线程库内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关标签: C++ 线程库