C++多线程例程

//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;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值