20200102

1 前++问题

int i = 1;

(++i)+(++i)=?

和编译器有关无固定答案,可能为6,可能为3等。

2 多线程

g++编译多线程

g++ main.cpp -o main -std=c++11 -lpthread

class A{
public:
    int m_count;
   // std::atomic<int> m_count;        //原子性包裹,防止多线程出现问题
    A(int vc = 0):m_count(vc){}
    int getCount() const { return m_count;}
    void setCount(){ m_count++;}
};

为了方便,全用public形式。

template <typename Iter>
void realWork(A& a,int& vVal,Iter iter1,Iter iter2){
    for(auto i = iter1;i != iter2;i++){
        vVal += *i;
        a.setCount();
    }
}

采用模板形式

void test11(){
    std::vector<int> arr;
    for(int i = 0;i < 10000000;i++){
        arr.push_back(rand()%100);
    }
    A a1;
    int Val1 = 0;
    realWork(a1,Val1,arr.begin(),arr.end());
    std::cout<<"a1.getCount() "<<a1.getCount()<<"  "<<Val1<<std::endl;
}

test11()只在单线程中跑(主线程),a1.getCount()为10000000。

void test12(){
	std::vector<int> arr;
	for(int i = 0;i < 10000000;i++){
		arr.push_back(rand()%100);
	}
	A a2;
	int Val2 = 0;
//	std::atomic<int&> Val2 = 0;
	auto iter1 = arr.begin() + (arr.size()/3);	//1/3分割点
	auto iter2 = arr.begin() + (arr.size()/3*2);	//2/3分割点
	auto iter3 = arr.end();
	std::thread t1([&a2,&Val2,iter1,iter2]{
		realWork(a2,Val2,iter1,iter2);
	});
	std::thread t2([&a2,&Val2,iter2,iter3]{
		realWork(a2,Val2,iter2,iter3);
	});
	realWork(a2,Val2,arr.begin(),iter1);
	t1.join();
	t2.join();
	std::cout<<"a2.getCount() "<<a2.getCount()<<"  "<<Val2<<std::endl;
}

test12()的最终结果不为10000000。void setCount(){ m_count++;}有可能多个线程同时访问m_count这个成员变量。

m_count++分为三部,内存到寄存器,寄存器运算之后,寄存器到内存。

void test13(){
	std::vector<int> arr;
	for(int i = 0;i < 10000000;i++){
		arr.push_back(rand()%100);
	}
	auto iter1 = arr.begin() + (arr.size()/3);	//1/3分割点
	auto iter2 = arr.begin() + (arr.size()/3*2);	//2/3分割点
	auto iter3 = arr.end();
	A a31;
	A a32;
	A a33;
	A a3;
	int Val31 = 0;
	int Val32 = 0;
	int Val33 = 0;
	int Val3 = 0;
	std::thread t31([&a31,&Val31,iter1,iter2]{
		realWork(a31,Val31,iter1,iter2);
	});
	std::thread t32([&a32,&Val32,iter2,iter3]{
		realWork(a32,Val32,iter2,iter3);
	});
	realWork(a33,Val33,arr.begin(),iter1);
	t31.join();
	t32.join();
	Val3 = Val31 + Val32 + Val33;
	a3.m_count = a31.m_count + a32.m_count + a33.m_count;
	std::cout<<"a3.getCount() "<<a3.getCount()<<"  "<<Val3<<std::endl;
}

上面把三个线程完全独立开,各自运算之后结果再汇总到一块,线程安全。

3 lambda表达式

void printAll(int a,int b,int c){
	std::cout<<a<<","<<b<<","<<c<<std::endl;
}

void printStr(const std::string& info1,const std::string& info2){
	std::cout<<"info1: "<<info1<<"  info2: "<<info2<<std::endl;
} 

void test2(){
	int x = 3;
	int y = 4;
	int z = 5;
	std::thread t1([=]{printAll(x,y,z);});
	//[=] 其中=表示后面函数所需的参数,按值去拷贝
	t1.join();
	std::thread t2(printAll,x,y,z);		//函数名称,参数列表
	t2.join();
	
	std::string s1("abc");
	std::string s2("def");
	std::thread t5([&]{printStr(s1,s2);});		//参数都已引用的方式传参
	t5.join();
	std::thread t6(printStr,s1,s2);		//效率最低
	t6.join();
	std::thread t7(printStr,std::cref(s1),std::cref(s2));	//cref常量引用
	t7.join();	
}

std::thread t([=]{func(val1,val2));[=]利用该局部范围内可以使用的参数(如果线程中函数需要的话),是以赋值形式传参,即传参过程中调用拷贝构造函数。[&]是以引用的形式传参。

4 所有代码

#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <atomic>
#include <mutex>	//临界区,临界体

void test0(){
	int i = 1;
	(++i)+(++i);
	std::cout<<i<<std::endl;
}

class A{
public:
//	int m_count;
	std::atomic<int> m_count;		//原子性包裹,防止多线程出现问题
	A(int vc = 0):m_count(vc){}
	int getCount() const { return m_count;}
	void setCount(){ m_count++;}
};

template <typename Iter>
void realWork(A& a,int& vVal,Iter iter1,Iter iter2){
	for(auto i = iter1;i != iter2;i++){
		vVal += *i;
		a.setCount();
	}
}

void test11(){
	std::vector<int> arr;
	for(int i = 0;i < 10000000;i++){
		arr.push_back(rand()%100);
	}
	A a1;
	int Val1 = 0;
	realWork(a1,Val1,arr.begin(),arr.end());
	std::cout<<"a1.getCount() "<<a1.getCount()<<"  "<<Val1<<std::endl;
}

void test12(){
	std::vector<int> arr;
	for(int i = 0;i < 10000000;i++){
		arr.push_back(rand()%100);
	}
	A a2;
	int Val2 = 0;
//	std::atomic<int&> Val2 = 0;
	auto iter1 = arr.begin() + (arr.size()/3);	//1/3分割点
	auto iter2 = arr.begin() + (arr.size()/3*2);	//2/3分割点
	auto iter3 = arr.end();
	std::thread t1([&a2,&Val2,iter1,iter2]{
		realWork(a2,Val2,iter1,iter2);
	});
	std::thread t2([&a2,&Val2,iter2,iter3]{
		realWork(a2,Val2,iter2,iter3);
	});
	realWork(a2,Val2,arr.begin(),iter1);
	t1.join();
	t2.join();
	std::cout<<"a2.getCount() "<<a2.getCount()<<"  "<<Val2<<std::endl;
}

void test13(){
	std::vector<int> arr;
	for(int i = 0;i < 10000000;i++){
		arr.push_back(rand()%100);
	}
	auto iter1 = arr.begin() + (arr.size()/3);	//1/3分割点
	auto iter2 = arr.begin() + (arr.size()/3*2);	//2/3分割点
	auto iter3 = arr.end();
	A a31;
	A a32;
	A a33;
	A a3;
	int Val31 = 0;
	int Val32 = 0;
	int Val33 = 0;
	int Val3 = 0;
	std::thread t31([&a31,&Val31,iter1,iter2]{
		realWork(a31,Val31,iter1,iter2);
	});
	std::thread t32([&a32,&Val32,iter2,iter3]{
		realWork(a32,Val32,iter2,iter3);
	});
	realWork(a33,Val33,arr.begin(),iter1);
	t31.join();
	t32.join();
	Val3 = Val31 + Val32 + Val33;
	a3.m_count = a31.m_count + a32.m_count + a33.m_count;
	std::cout<<"a3.getCount() "<<a3.getCount()<<"  "<<Val3<<std::endl;
}

void test1(){
	test11();
	test12();
	test13();
}

void printAll(int a,int b,int c){
	std::cout<<a<<","<<b<<","<<c<<std::endl;
}

void printStr(const std::string& info1,const std::string& info2){
	std::cout<<"info1: "<<info1<<"  info2: "<<info2<<std::endl;
} 

void test2(){
	int x = 3;
	int y = 4;
	int z = 5;
	std::thread t1([=]{printAll(x,y,z);});
	//[=] 其中=表示后面函数所需的参数,按值去拷贝
	t1.join();
	std::thread t2(printAll,x,y,z);		//函数名称,参数列表
	t2.join();
	
	std::string s1("abc");
	std::string s2("def");
	std::thread t5([&]{printStr(s1,s2);});		//参数都已引用的方式传参
	t5.join();
	std::thread t6(printStr,s1,s2);		//效率最低
	t6.join();
	std::thread t7(printStr,std::cref(s1),std::cref(s2));	//cref常量引用
	t7.join();	
}

int main(){
//	test0();
	test1();
//	test2();
	return 0;
}
	

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值