//lock_guard
#include <iostream>
#include <thread> //线程
#include <mutex> //锁
using namespace std;
void Fun_1(); //声明分支线程函数Fun_1()
void Fun_2(); //声明分支线程函数Fun_2()
unsigned int counter = 0; //定义变量counter,通过变量counter的变化来观察线程同步情况
std::mutex mtx; //定义mutex类的对象mtx构造互斥元,互斥占有一个变量,一段时间内仅一个线程可以访问
int main(){
std::thread thrd_1(Fun_1); //创建线程thrd_1,thrd_1调用函数Fun_1
std::thread thrd_2(Fun_2); //创建线程thrd_2,thrd_2调用函数Fun_2
thrd_1.join(); //join()函数启动子线程而阻塞主线程,子线程会按照开启的先后顺序同步运行,当子线程运行结束后,才会继续运行主线程
thrd_2.join(); //启动线程thrd_2,并且阻塞主线程,等到线程thrd_2运行结束后,再继续运行主线程;
cout<<"counter= "<< counter <<endl;
return 0;
}
void Fun_1(){
while (true){
/*std::lock_guard类模板,用于自动锁定解锁,直到对象作用域结束。在 lock_guard 对象构造时,传入的mutex对象 mtx 会被当前线程锁住。在lock_guard 对象被析构时,它所管理的mutex对象mtx会自动解锁*/
std::lock_guard<std::mutex> mtx_locker(mtx);
counter++;
if (counter < 20)cout << "Function 1 counting ! counter=" << counter << endl;
else break;
}
}
void Fun_2(){
while (true){
/*std::lock_guard类模板,用于自动锁定解锁,直到对象作用域结束。在 lock_guard 对象构造时,传入的mutex对象 mtx 会被当前线程锁住。在lock_guard 对象被析构时,它所管理的mutex对象mtx会自动解锁*/
std::lock_guard<std::mutex> mtx_locker(mtx);
counter++;
if (counter < 20)cout << "Function 2 counting ! counter=" << counter << endl;
else break;
}
}
//lock与unlock
#include<bits/stdc++.h>
#include<thread>
#include<mutex>
using namespace std;
mutex mu;
void func(int num){
//mu.lock();//上锁
lock_guard<mutex> guard(mu);//用mu构造guard对象,析构时就会解锁mu
for(int i=1;i<=10;i++)
cout<<num<<" : "<<i<<endl;
//mu.unlock();//解锁
}
int main(){
//1、查看CPU最多支持多少线程
cout<<thread::hardware_concurrency()<<endl;
//2、主线程与子线程同时往下执行
thread t1(func,1);
t1.detach();
//3、主线程等子线程执行完再往下执行
thread t2(func,2);
thread t3(func,3);
t2.join();
t3.join();
return 0;
}
//unique_lock
#include<bits/stdc++.h>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
deque<int> q;
mutex mu;
condition_variable cond;
void fun1(){
int cnt=10;//生产了十个货物
while(cnt>0){//有货物
unique_lock<mutex> locker(mu);//上锁
q.push_back(cnt);//压入缓冲区
locker.unlock();//解锁
//cond.notify_one();//激活一个等待线程
cond.notify_all();//激活所有等待线程
this_thread::sleep_for(chrono::milliseconds(100));//等0.1秒
cnt--;//货物数减一
}
}
void fun2(){
int data=0;//物品编号
while(data!=1){//缓冲区未是最后一件物品
unique_lock<mutex> locker(mu);//上锁
cond.wait(locker);//解锁locker并等待cond满足再给locker上锁
data=q.back();//读入
q.pop_back();//弹出
locker.unlock();//解锁
cout<<data<<endl;//输出物品编号
}
}
int main(){
thread t2(fun2);
thread t1(fun1);//若这行代码在上一行之前执行,会少了输出第一个10
t1.join();
t2.join();
return 0;
}
//调用
#include<mutex>
#include<fstream>
#include<future>
using namespace std;
class A{
public:
void f(int x,char c){}
int operator()(int n){return 0;}
};
void foo(int x){}
int main(){
A a;
thread t1(a,6);//传递a的考贝给子线程
thread t2(ref(a),6);//传递a的引用给子线程
thread t3(move(a),6);//传递a本身给子线程,a在主线程中将不再有效
thread t4(A(),6);//传递临时创建的a对象给子线程
thread t5(foo,6);//传递一个函数给子线程
thread t6([](int x){return x*x;},6);//传递一个函数给子线程
thread t7(&A::f,a,8,'w');//传递a的考贝的成员函数给子线程
thread t8(&A::f,&a,8,'w');//传递a的地址的成员函数给子线程(注意ref(a)与&a的区别)
async(launch::async,a,6);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
return 0;
}
//future与promise
#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<future>
using namespace std;
void func(int n,int& x){x=n;cout<<"n1="<<n<<endl;}
int func2(int n){cout<<"n2="<<n<<endl;return n;}
int func3(shared_future<int> f){int n=f.get();cout<<"n3="<<n<<endl;return n;}
int func4(future<int>& f){int n=f.get();cout<<"n4="<<n<<endl;return n;}
int main(){
//使用引用,从子线程传递值到父线程
int x;
thread t1(func,1,ref(x));
t1.join();
cout<<"x="<<x<<endl<<endl;
//在此基础上要补充很多锁,所以不推荐使用
//使用future,从子线程传递值到父线程
//第一种情况:不会创建子线程,执行get函数时当普通函数调用
future<int> fu1=async(launch::deferred,func2,2);
cout<<"x1="<<fu1.get()<<endl<<endl;//会等待子线程结束得数据再往下走
//第二种情况:会立即创建子线程执行
future<int> fu2=async(launch::async,func2,3);
cout<<"x2="<<fu2.get()<<endl<<endl;//会等待子线程结束得数据再往下走
//第三种情况:让系统自己决定
future<int> fu3=async(func2,4);
cout<<"x3="<<fu3.get()<<endl<<endl;//会等待子线程结束得数据再往下走
//使用promise,子线程获取父进程参数
promise<int> p;
future<int> f=p.get_future();
shared_future<int> sf=f.share();
future<int>fff1 =async(launch::async,func3,sf);
future<int>fff2 =async(launch::async,func3,sf);
p.set_value(5);
cout<<fff1.get()<<' '<<fff2.get()<<endl<<endl;
//同上,但这次不用共享future属性
promise<int> tmpp;//定义一个promise对象
future<int> tmpin=tmpp.get_future();//定义一个future对象,在将来接收tmpp值
future<int> tmpout=async(launch::async,func4,ref(tmpin));//跑子线程
tmpp.set_value(6);//设置值
cout<<tmpout.get()<<endl<<endl;
return 0;
}