概述
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;
}
最后
以上就是魔幻萝莉为你收集整理的202001021 前++问题2 多线程3 lambda表达式4 所有代码的全部内容,希望文章能够帮你解决202001021 前++问题2 多线程3 lambda表达式4 所有代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复