当前位置: 首页 > news >正文

C++11语言级别的多线程

关键字和语法方面

auto 可以根据右值推导出右值类型,然后左边变量类型就已知了

nullptr:指针专用,能够与指针进行区别,以前使用的NULL位define NULL 0

foreach(Type val:container)=>底层就是通过指针或者迭代器来实现的
{
        cout<<val;
}

右值引用:move移动语义和forward类型完美转发函数

模板的一个新特新:typename... A 表示可变参数(类型参数)

智能指针,容器,绑定器和function都在之前的作品中

2. C++11语言级别的多线程

头文件<thread>

1. 如何启动一个线程

std::thread传入一个线程所需要的函数,然后后面为传入的参数,线程自动挡开启

2. 子线程如何结束

子线程函数运行完成,线程就自动结束了

3.主线程如何处理子线程

主线程等待子线程结束才可以继续运行(join),或者把子线程设置为分离线程(detach)

睡眠函数:阻塞2秒

    std::this_thread::sleep_for(std::chrono::seconds(2));
线程之间的互斥操作

多线程程序存在竞态条件

多线程程序执行的结构是一致的,不会随着CPU对线程的调用顺序而产生不同的结果

线程间的互斥使用互斥锁

包含头文件mutex

#include <bits/stdc++.h>
using namespace std;std::mutex mtx;int mycount = 100;void sellTicket(int index){while(mycount>0){//锁+双重判断mtx.lock();if(mycount>0){cout<<"卖出第:"<<mycount<<"张票"<<endl;mycount--;mtx.unlock();this_thread::sleep_for(chrono::milliseconds(2));}}
}int main(){list<thread> tlist;for(int i=0;i<3;i++){tlist.push_back(thread(sellTicket,i));}for(auto &t:tlist){t.join();}return 0;
}

可以使用lock_guard<std::mutex> lock(mtx)代替mtx,这个会在出作用域的时候析构

note:lock_guard只能用在简单的临界区代码段的互斥操作中,构造时立即锁定互斥量,析构时自动解锁,​​不允许手动操作​​(如提前解锁)。

unique_lock //使用类似于unique_ptr

unique_lock //不仅可以在简单临界区代码段的互斥操作中,还能用在函数调用过程中

线程之间的同步通信机制

代码实现生产者消费者模型

#include <bits/stdc++.h>
using namespace std;mutex mtx;
//条件变量做线程之间的通信
std::condition_variable cv;
//实现生产者生产一个物品,消费者消费
//实现线程资源队列
class myQueue{
public:void put(int val){unique_lock<mutex> lck(mtx);while(!que.empty()){//que不为空,那么通知消费者区消费,消费者消费结束,再进行生产//生产者进入阻塞,并把锁释放掉unique_lock<mutex> lck(mtx);cv.wait(lck);//进入等待状态}que.push(val);cv.notify_all();//同时其它所有线程,生产了产品cout<<"生产者生产:"<<val<<endl;}int get(){unique_lock<mutex> lck(mtx);while(que.empty()){cv.wait(lck);//进入等待状态}int val = que.front();que.pop();cv.notify_all();cout<<"消费者消费:"<<val<<endl;return val;}
private:queue<int> que;
};
void producer(myQueue *que){for(int i=1;i<=10;++i){que->put(i);std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}
void consumer(myQueue *que){for(int i=1;i<=10;++i){que->get();std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}
int main(){myQueue que;std::thread t1(producer,&que);std::thread t2(consumer,&que);t1.join();t2.join();return 0;
}

notify_all告知等待所有线程,而notify_one告知一个线程

每个线程如果被wait阻塞,就会挂到一个阻塞队列中,然后通过notify进行唤醒 

原子操作

互斥锁是比较重的,临界区代码做的事情稍稍复杂

系统理论,CAS保证上面++ --操作的原子特性就足够了

#include <bits/stdc++.h>
using namespace std;volatile atomic_bool isReady(false);
volatile atomic_int mycount(0);
void task(){while(!isReady){this_thread::yield();//线程让出当前CPU时间片,等待下一次调度}for(int i=0;i<100;i++){mycount++;}
}int main(){list<thread> tlist;for(int i=0;i<10;++i){tlist.emplace_back(task);}this_thread::sleep_for(chrono::seconds(3));isReady = true;for(auto &i:tlist){i.join();}cout<<"count:"<<mycount<<endl;return 0;
}

http://www.xdnf.cn/news/573553.html

相关文章:

  • 5月21日
  • 云渲染技术解析与渲酷平台深度测评:如何实现高效3D创作?
  • 为什么可以不重写m1方法
  • Multi-Query Attention:传统自注意力( Self-Attention)优化显存和加速方案
  • IP核警告,Bus Interface ‘AD_clk‘: ASSOCIATED_BUSIF bus parameter is missing.
  • python生成requirements.txt文件
  • ABC 353
  • ROS2 CV_bridge与opencv版本冲突
  • 学习 Pinia 状态管理【Plan - May - Week 2】
  • 创建一个element plus项目
  • [C++入门]类和对象下
  • 东莞一锂离子电池公司IPO终止,客户与供应商重叠,社保缴纳情况引疑
  • GitLab 配置 webhook
  • 越小越优先和越大越优先
  • oracle使用SPM控制执行计划
  • 使用Redis的Bitmap实现了签到功能
  • iPaaS集成平台技术选型关注哪些指标?
  • HJ20 密码验证合格程序【牛客网】
  • 测试W5500的第4步_使用ioLibrary库创建UDP客户端和服务器端
  • 数据结构核心知识总结:从基础到应用
  • 6-码蹄集600题基础python篇
  • Mysql数据库相关命令及操作
  • 链表-两两交换链表中的节点
  • Mysql差异备份与恢复
  • Python图像处理全攻略:从基础到前沿技术深度剖析
  • 极大似然估计与机器学习
  • python查询elasticsearch 获取指定字段的值的list
  • 操作系统期末复习(一)
  • 淘宝扭蛋机小程序开发:开启电商娱乐新玩法
  • 工程项目交付质量低?如何构建标准化管理体系?