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

哈尔滨模板建站定制网站独立网站

哈尔滨模板建站定制网站,独立网站,免费申请域名和空间,网页设计代码一日游伊露岛C11新特性有哪些 并发线程(thread)原子类型互斥量(Mutex)锁(lock) 并发 线程(thread) 创建线程对象后,必须要提供线程关联函数。两者都聚齐了,才能启动线程。…

C++11新特性有哪些

  • 并发
    • 线程(thread)
    • 原子类型
    • 互斥量(Mutex)
    • 锁(lock)

并发

线程(thread)

在这里插入图片描述

  • 创建线程对象后,必须要提供线程关联函数。两者都聚齐了,才能启动线程。线程函数一般情况下可按照以下四种方式提供:
    • 函数指针
    • lambda表达式
    • 函数对象
    • 包装器(function)
void ThreadFunc(int a) {cout << "Thread1" << a << endl;
}void T()
{cout << "hello" << endl;
}class TF
{
public:void TT(){cout << "NI" << endl;}void operator()(){cout << "Thread3" << endl;}
};int main()
{// 线程函数为函数指针thread t1(ThreadFunc, 10);// 线程函数为lambda表达式thread t2([] {cout << "Thread2" << endl; });// 线程函数为函数对象TF tf;thread t3(tf);thread t5(&TF::TT, TF());//线程函数为包装器function<void()> t = T;thread t4(t);t1.join();t2.join();t3.join();t4.join();t5.join();cout << "Main thread!" << endl;return 0;
}
  • 禁止拷贝线程对象:thread类 不允许拷贝构造以及赋值,但是可以移动构造和移动赋值,即一个线程对象关联的 线程的状态 转移给 其他线程对象,转移期间不影响线程的执行

  • 线程函数参数

    • 线程函数的参数是以 值拷贝 的方式 拷贝到线程栈空间中的,实际引用的是 线程栈中的拷贝,而不是外部实参。所以,即使参数是引用类型,最后也不能把改变后的结果带到外面
    • 注意:如果线程参数是类成员函数时,必须将this作为线程函数参数
  • 可以通过 joinable()函数 判断线程是否是有效的,如果是以下任意情况,则线程无效:

    • 线程对象没有关联函数
    • 线程对象的状态已经转移给其他线程对象
    • 线程已经调用join 或者detach结束

原子类型

  • 声明一个类型为T 的原子类型变量t:
atmoic<T> t;    // 声明一个类型为T的原子类型变量t
  • 特点:

    • 如果是对原子类型的变量进行修改,就不需要加锁了。线程会自动地互斥访问原子类型

    • 原子类型是不允许拷贝和赋值的,因为atmoic模板类中的拷贝构造、移动构造、赋值运算符重载都被删除掉了

#include <atomic>
int main()
{atomic<int> a1(0);//atomic<int> a2(a1);   // 编译失败atomic<int> a2(0);//a2 = a1;               // 编译失败return 0;
}
  • 实例:

    该例中,使用原子变量后 就不再需要加锁了

    在这里插入图片描述

互斥量(Mutex)

原子类型可以保证一个变量的安全性,但是对于一段代码的安全性,我们只能通过 互斥量和锁 来实现

  • 普通互斥量(std:: mutex)

    在这里插入图片描述

    • 注意,线程函数调用 lock() 时,可能会发生以下三种情况:

      • 如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁
      • 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住
      • 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)
    • 线程函数调用 try_lock() 时,可能会发生以下三种情况:

      • 如果当前互斥量没有被其他线程占有,则该线程锁住互斥量,直到该线程调用 unlock释放互斥量
      • 如果当前互斥量被其他线程锁住,则当前调用线程返回 false,而并不会被阻塞掉
      • 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)
  • 递归互斥量(std:: recursive_mutex)

    • 递归互斥锁 允许同一个线程对互斥量多次上锁(即递归上锁),来获得对互斥量对象的多层所有权。释放互斥量时需要调用相同次数的 unlock()。除此之外,std::recursive_mutex 的特性和 std::mutex 大致相同

    • 这对于递归函数 可能需要在同一线程中多次获取锁的情况很有用:

#include <iostream>
#include <mutex>
#include <thread>std::recursive_mutex myRecursiveMutex;void recursiveAccess(int depth) {std::unique_lock<std::recursive_mutex> lock(myRecursiveMutex);if (depth > 0) {recursiveAccess(depth - 1);}// 访问共享资源的代码std::cout << "Accessing shared resource at depth " << depth << "...\n";
}int main() {std::thread t1(recursiveAccess, 3);t1.join();return 0;
}
  • 定时互斥量(std::timed_mutex)

  • 比 std::mutex 多了两个成员函数,try_lock_for(),try_lock_until() :

    • try_lock_for():函数参数表示一个时间范围,在这一段时间范围之内线程如果没有获得锁 则保持阻塞;如果在此期间其他线程释放了锁,则该线程可获得该互斥锁;如果超时(指定时间范围内没有获得锁),则函数调用返回false。
 timed_mutex myMutex;chrono::milliseconds timeout(100);  //100毫秒if (myMutex.try_lock_for(timeout)){//在100毫秒内获取了锁//业务代码myMutex.unlock();  //释放锁}else{//在100毫秒内没有获取锁//业务代码}
  • try_lock_until():函数参数表示一个时刻,在这一时刻之前线程如果没有获得锁则保持阻塞;如果在此时刻前其他线程释放了锁,则该线程可获得该互斥锁;如果超过指定时刻没有获得锁,则函数调用返回false。

  • 定时递归互斥量(std::recursive_timed_mutex)

    允许同一线程多次获取锁,并提供了超时功能。与std::timed_mutex一样,std::recursive_timed_mutex也提供了try_lock_for()和try_lock_until()方法

锁(lock)

这里主要介绍两种RAII方式的锁封装(std::lock_guard和std::unique_lock),可以动态的释放锁资源,防止线程由于编码失误导致一直持有锁。

  • std::lock_gurad 是 C++11 中定义的模板类,取代了mutex的lock和unlock函数。定义如下:

    在这里插入图片描述

    • lock_guard类模板通过RAII来封装。在需要加锁的地方,只需要用互斥量实例化一个lock_guard对象,此时类内调用构造函数成功上锁;出作用域前,lock_guard对象要被销毁,调用析构函数自动解锁,可以有效避免死锁问题。
    • lock_guard对象之间是不能拷贝和赋值的
    • lock_guard的缺陷:太单一,用户没有办法对该锁进行控制,因此C++11又提供了unique_lock。
  • 独占锁(unique_lock)

与lock_guard不同的是,unique_lock更加的灵活(但效率上差一点,内存占用多一点),提供了更多的成员函数:

  • 上锁/解锁操作:lock、try_lock、try_lock_for、try_lock_until和unlock
  //1.立即上锁std::mutex mtx;std::unique_lock<std::mutex> lck(mtx);//2.延迟上锁std::unique_lock<std::mutex> lck(mtx, std::defer_lock); //只是创建对象,不上锁lck.lock(); // 此时才上锁if(lck.try_lock()){// 已获得锁}lck.unlock();
  • 修改操作:移动赋值、交换即swap(与另一个unique_lock对象互换所管理的互斥量所有权)、释放即release(返回它所管理的互斥量对象的指针,并释放所有权)
std::unique_lock<std::mutex> ul1(mtx);std::unique_lock<std::mutex> ul2 = std::move(ul1); // 把ul1的锁转移到ul2上,即现在是ul1对mtx上锁if (!ul1.owns_lock()) // 现在 ul1 应该不再持有锁了{assert(true);}
  • 获取属性:owns_lock(返回当前对象是否上了锁)、operator bool()(与owns_lock()的功能相同)、mutex(返回当前unique_lock所管理的互斥量的指针)
  if(lck.owns_lock()){// 此时拥有锁}auto* m = lck.mutex();
http://www.dtcms.com/wzjs/522732.html

相关文章:

  • 中国建设银行北京分行网站网站百度收录秒收方法
  • wordpress制作评论模板seo排名优化排行
  • 网站开发注销代码批量关键词排名查询工具
  • 商业网站建设教程seo的推广技巧
  • 泰安网站开发手机网站
  • 做网站用jsp和html网络营销的主要方式
  • 汽车网站正在建设中模板中国seo排行榜
  • 合肥百度搜索排名优化快速seo优化
  • 淘宝网站怎么做的好程序员培训机构排名前十
  • 如何做内网网站建站流程主要有哪些
  • 旅游网站建设的目的推广app大全
  • 昆明企业网站开发游戏推广怎么快速拉人
  • 外贸网站建设和优化巩义网站推广优化
  • wordpress 4评测信息流优化师职业规划
  • 济南网站建设培训b站推广网站入口202
  • 教育网站官网入口网站如何优化一个关键词
  • 党刊网站怎么做游戏推广员招聘
  • 上海营销型企业网站企点qq官网
  • 网站建设的资金风险优化网站教程
  • 怎么登陆网站后台管理系统sem外包
  • 怎么自己做个网站广告投放网站
  • 行业网站建设深圳公司网络营销的含义
  • 手机代码编辑器seo店铺描述
  • 阿里云服务器ecs网站seo方案策划书
  • 浙江网站建设品牌网站前期推广
  • 企业申请完域名以后 怎么把网站运行起来网站优化推广方法
  • 手表网站大全360网站关键词排名优化
  • 网站建设公司每年可以做多少个网站打造龙头建设示范
  • 做网站留后门是怎么回事西安百度seo代理
  • 青岛城阳 软件网站开发whois查询 站长工具