c++多线程初探

一般使用方法

atomic

原子类型 一般运用于变量 本身相当于有自动锁

   atomic<bool> b(true);
   b = false;

thread_local

thread_local 定义的变量在每个线程都保存一份副本,互不干扰在线程退出时候自动销毁

thread_local int g_k = 0

detch与join

主进程与线程分离detach()后子线程在后台独立继续运行,
主线程无法再取得子线程的控制权,即使主线程结束,子线程未执行也不会结束。
当主线程结束时,由运行时库负责清理与子线程相关的资源。
实际应用如让一个文字处理应用同时编辑多个文档,让每个文档处理窗口拥有自己的线程,
每个线程运行同样的代码,并隔离不同窗口处理的数据
join当前线程完成退出后才能继续下一个线程或者继续主线程

线程传入可修改的参数

projects5

void proc(int &a){
    a = a+100;
    cout<<"a = "<<a<<endl;
    cout<<"thread_id = "<<std::this_thread::get_id()<<endl;
}

bind与thread传递引用时必须外层使用ref来进行传递

int a=9;
thread th2(proc,ref(a));
//主线程等待子线程运行完之后才继续运行
th2.join();

结果
在这里插入图片描述

lock_guard< mutex >超过使用范围自动解锁

void proc1(int a){
    //m.lock();
    lock_guard<mutex> g1(m);
    cout<<"proc1 change a"<<endl;
    cout<<"proc1 before a = "<<a<<endl;
    a = a+2;
    cout<<"proc1 after a = "<<a<<endl; 
    //cout<<"proc1 thread_id = "<<std::this_thread::get_id()<<endl;
    //m.unlock();
}
void proc2(int a){
    //m.lock();
    {
        lock_guard<mutex> g2(m);//用大括号限制锁的范围  
        cout<<"proc2 change a"<<endl;
        cout<<"proc2 before a = "<<a<<endl;
        a = a+4;
        cout<<"proc2 after a = "<<a<<endl; 
        //cout<<"proc2 thread_id = "<<std::this_thread::get_id()<<endl;
        //m.unlock();
    }
    cout<<"beyond 2"<<endl;
    cout<<"beyond 3"<<endl;
}
    thread th2(proc2,a);
    thread th1(proc1,a);
    th1.join();
    th2.join();

结果
锁一旦放出,则后续输出顺序不定
在这里插入图片描述

各种锁的方式

defer_lock

void proc3(int a){
    unique_lock<mutex> g1(m,defer_lock);//初始化了一个没有加锁的mutex
    g1.lock();//使用g1进行m的管理,在这抢赢了4 但是输出顺序乱了
    cout<<"xxxxxxxxxx"<<endl;
    //g1.lock();  //在这抢不过4
    cout<<"proc3 change a"<<endl;
    cout<<"proc3 before a = "<<a<<endl;
    a = a+3;
    cout<<"proc3 after a = "<<a<<endl; 
    //cout<<"proc1 thread_id = "<<std::this_thread::get_id()<<endl;
    //m.unlock();
}//自动释放锁

try_to_lock

尝试加锁如果没有锁定成功会立即返回,失败后不会阻塞线程,而是继续往下执行

void proc4(int a){
    unique_lock<mutex> g2(m,try_to_lock);
    if(g2.owns_lock()){
        cout<<"proc4 change a"<<endl;
        cout<<"proc4 before a = "<<a<<endl;
        a = a+4;
        cout<<"proc4 after a = "<<a<<endl; 
    }
    else {
        cout<<"beyond 4"<<endl;
        cout<<"beyond 5"<<endl;
    }

}//自动解锁

adopt_lock

void proc5(int a){
    m.lock();
    //收养锁,托管锁,发生异常也不会没有解锁而产生死锁
    lock_guard<mutex> g5(m,adopt_lock);
    cout<<"proc5 change a"<<endl;
    cout<<"proc5 before a = "<<a<<endl;
    a = a+5;
    cout<<"proc5 after a = "<<a<<endl; 
}
thread th5(proc5,a);
thread th3(proc3,a);
thread th4(proc4,a);
th5.join();
th3.join();
th4.join();

结果
由于try_to_lock的存在,所以并没有完全按照顺序执行 p4的语句混在里面
在这里插入图片描述

异步线程

异步线程 凭借future对象进行get()结果,如果结果没出子线程没有return 就一直阻塞

double proc6(const double &a,const double &b){
    double c = a + b;
    _sleep(3000);
    return c;
}
//生产者
void producer(){
    int data1;
    while(1){
        if(c<3)//限制产品数量
        {
            {
                data1 = rand();
                unique_lock<mutex> locker(m);//锁
                q.push_front(data1);
                cout<<"message is pushed"<<endl;
                cond.notify_one();//唤醒任意一个等待的线程
                ++c;
            }//锁的范围
             _sleep(500);
        }
    }
}

future

double a1 = 2.3;
double b1 = 6.7;
future<double> fu = async(proc6,a1,b1);
cout<<"the result is doing"<<endl;
cout<<"waiting for a while"<<endl;
cout<<"result is : "<<fu.get()<<endl;//阻塞主线程,直至异步线程return 

结果
一直等待到子线程出结果
在这里插入图片描述
在这里插入图片描述

shared_future

可以get多次

shared_future<double> fu = async(proc6,a1,b1);
cout<<"the result is doing"<<endl;
cout<<"waiting for a while"<<endl;
cout<<"result is : "<<fu.get()<<endl;//阻塞主线程,直至异步线程return 
cout<<"result is : "<<fu.get()<<endl;//阻塞主线程,直至异步线程return 

结果
在这里插入图片描述

生产者和消费者

生产者

//生产者
void producer(){
    int data1;
    while(1){
        if(c<3)//限制产品数量
        {
            {
                data1 = rand();
                unique_lock<mutex> locker(m);//锁
                q.push_front(data1);
                cout<<"message is pushed"<<endl;
                cond.notify_one();//唤醒任意一个等待的线程
                ++c;
            }//锁的范围
             _sleep(500);
        }
    }
}

消费者

wait(unique_lock) wait会自动释放锁,并阻塞当前线程,当被唤醒时自动调用lock上锁

void consumer1(){
    int data2;
    while(1){
        {
            unique_lock<mutex> locker(m);
            while (q.empty())
            {
                cond.wait(locker);//阻塞前会先解锁
            }
            data2=q.back();
            q.pop_back();
            cout<<"consumer1 get message"<<endl;
            --c;
        }//上锁的范围
        _sleep(600);
    }   
}
void consumer2(){
    int data2;
    while(1){
        {
            unique_lock<mutex> locker(m);
            while (q.empty())
            {
                cond.wait(locker);//阻塞前会先解锁
            }
            data2=q.back();
            q.pop_back();
            cout<<"consumer2 get message"<<endl;
            --c;
        }//上锁的范围
        _sleep(700);
    }   
}

void consumer3(){
    int data2;
    while(1){
        {
            unique_lock<mutex> locker(m);
            while (q.empty())
            {
                cond.wait(locker);//阻塞前会先解锁
            }
            data2=q.back();
            q.pop_back();
            cout<<"consumer3 get message"<<endl;
            --c;
        }//上锁的范围
        _sleep(1500);
    }   
}

结果
在这里插入图片描述

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值