首页 > 编程语言 >现代C++(Modern C++)基本用法实践:八、线程支持

现代C++(Modern C++)基本用法实践:八、线程支持

时间:2023-07-13 13:00:11浏览次数:40  
标签:std join LOG thread int Modern t2 C++ 线程

概述

在c++11之前,c++并未对线程编程提供直接的支持。在c++11之后,支持了线程管理、同步、条件变量等支持。
在其他的c++库中(例如UE的线程库)还增加了多任务模型的抽象。

用法举例

参考测试项目的modrenc_auto_decltype.cpp文件
主要内容:

  • 线程的创建
  • 使用future&async进行异步操作
  • 使用future&promise进行异步操作
  • 有锁同步
  • 无锁同步(原子操作)
#include "ModernCppTestHeader.h"
#include <thread>
#include <future>
#include <mutex>


namespace n_thread {
	void increment(int n)
	{
		int i = 0;
		while (++i < n)
		{
			LOG_VAR(i);
		}
	}

	int accumulate(int n)
	{
		int r = 0;
		for (size_t i = 0; i <= n; i++)
		{
			r += i;
		}

		LOG_VAR(r);
		return r;
	}

	void accumulate_p(int n, std::promise<int> p)
	{
		int r = accumulate(n);
		p.set_value(r);
	}

	std::mutex mtx;
	void print_block_sync(int n, char c)
	{
		std::lock_guard<std::mutex> guard(mtx);

		for (int i = 0; i < n; ++i) {
			std::cout << c;
		}
		std::cout << '\n';
	}

	void print_block_async(int n, char c)
	{
		for (int i = 0; i < n; ++i) {
			std::cout << c;
		}
		std::cout << '\n';
	}

	class Number
	{
	public:
		Number(int v) :v(v) {}
		int v;
	};

	

	void counter_async(Number* num, int n)
	{
		for (int i = 0; i < n; ++i) {
			num->v++;
		}
	}

	void counter_sync(std::atomic<int>* v, int n)
	{
		for (int i = 0; i < n; ++i) {
			++(*v);
		}
	}
}

void thread_test()
{
	LOG_FUNC();


	LOG_TAG("线程创建");
	{
		std::thread t(n_thread::increment, 3);
		t.join();
		LOG("main thread goes on");
	}


	LOG_TAG("异步操作 使用 future&async");
	{
		std::future<int> f = std::async(n_thread::accumulate, 3);

		LOG("等待异步计算");
		int sum = f.get();
		LOG_VAR(sum);
	}


	LOG_TAG("异步操作 使用 future&promise");
	{
		std::promise<int> p;
		std::future<int> f = p.get_future();
		std::thread t(n_thread::accumulate_p, 3, std::move(p));
		LOG("等待异步计算");
		int sum = f.get();
		LOG_VAR(sum);
		t.join();
	}


	LOG_TAG("有锁同步");
	{
		{
			LOG("不同步");
			std::thread t1(n_thread::print_block_async, 50, '#');
			std::thread t2(n_thread::print_block_async, 50, '$');
			t1.join();
			t2.join();
		}

		{
			LOG("同步");
			std::thread t1(n_thread::print_block_sync, 50, '#');
			std::thread t2(n_thread::print_block_sync, 50, '$');
			t1.join();
			t2.join();
		}
	}

	LOG_TAG("无锁同步");
	{
		{
			LOG("不同步, 有可能能正确计算,但是不稳定");
			n_thread::Number n(0);
			std::thread t1(n_thread::counter_async, &n, 100000);
			std::thread t2(n_thread::counter_async, &n, 100000);
			t1.join();
			t2.join();
			LOG_VAR(n.v);
		}

		{
			LOG("同步");
			std::atomic<int> v(0);
			std::thread t1(n_thread::counter_sync, &v, 100000);
			std::thread t2(n_thread::counter_sync, &v, 100000);
			t1.join();
			t2.join();
			LOG_VAR(v);
		}
	}

}

标签:std,join,LOG,thread,int,Modern,t2,C++,线程
From: https://www.cnblogs.com/hggzhang/p/17545943.html

相关文章

  • PAT-甲级-1007 Maximum Subsequence Sum C++
    Givenasequenceof K integers{ N1​, N2​,..., N​K }.Acontinuoussubsequenceisdefinedtobe{ Ni​, Ni+1​,..., Nj​ }where 1≤i≤j≤K.TheMaximumSubsequenceisthecontinuoussubsequencewhichhasthelargestsumofitselements.Fore......
  • c++ day 8
    今天终于来学习时间复杂度了当分析算法的时间复杂度时,我们通常关注以下几个方面来确定算法的执行时间:循环次数:循环是算法中常见的结构,它会重复执行一段代码。时间复杂度取决于循环的次数。例如,一个循环从1到n的遍历,时间复杂度就是O(n)。嵌套循环:如果算法中存在多个嵌套循环......
  • Java面试高频技术线程池,源码笔记答案全纪录
    有一定的java基础(线程),尤其是正要或正准备找工作的童鞋如果想在众多面试者中脱颖而出,你就需要多准备一些知识点,多刷一些面试题。而对于企业而言,有这么多的选择那我们就提高面试门槛,可能我需要的仅仅是CRUD的初中级,但我也希望你能了解JVM、多线程、Spring源码、Sql优化、分布......
  • 【C++开源库】Windows 下编译 libcurl 库
    Whatislibcurl?libcurl是一个跨平台的网络协议库,支持http,https,ftp,gopher,telnet,dict,file,和ldap协议。libcurl同样支持HTTPS证书授权,HTTPPOST,HTTPPUT,FTP上传,HTTP基本表单上传,代理,cookies和用户认证。想要知道更多关于libcurl的介绍,可以到官网......
  • SpringBoot中使用Netty开发WebSocket服务-netty-websocket-spring-boot-starter开源项
    场景SpringBoot+Vue整合WebSocket实现前后端消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114392573SpringCloud(若依微服务版为例)集成WebSocket实现前后端的消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114480731若依前后......
  • C++ 数据封装
     所有的C++程序都有以下两个基本要素:程序语句(代码):这是程序中执行动作的部分,它们被称为函数。程序数据:数据是程序的信息,会受到程序函数的影响。封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装......
  • C++ 接口(抽象类)
     接口描述了类的行为和功能,而不需要完成类的特定实现。C++接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。https://www.lekaowang.com/cfa/oitt/......
  • Java入门12(多线程)
    多线程线程的实现方式继承Thread类:一旦继承了Thread类,就不能再继承其他类了,可拓展性差实现Runnable接口:仍然可以继承其他类,可拓展性较好使用线程池继承Thread类​ 不能通过线程对象调用run()方法,需要通过t1.start()方法,使线程进入到就绪状态,只要进入到就绪状态......
  • C++计算机学院2023年度小学期编程实践课程(图书管理系统)[2023-07-12]
    C++计算机学院2023年度小学期编程实践课程(图书管理系统)[2023-07-12]计算机学院2023年度小学期编程实践课程上机实验题目(一)基于学生结构体数组的图书管理系统(40分)定义学生结构体类型的数组,静态初始化学生信息(不包括借书信息)。图书使用二维字符数组或字符指针数组单独......
  • C++ 傅里叶频谱的计算以及应用
    一维傅里叶频谱的计算#include<stdio.h>#include<math.h>#definepi3.1415926#definerows3#definecolums5typedefstruct{floatre;//reallyfloatim;//imaginary}complex,*pcomplex;complexcomplexadd(complexa,complexb)//复数加......