C++11 ,封装了thread的多线程的类,这样对多线程的使用更加方便。

多线程的原理我不加赘述,可以参看操作系统等参考书。

多线程代码可以最大化利用计算机性能资源,提高代码的运行效率,是常用优化方法。

我不是C++大神,初学阶段的菜鸟而已,很多问题我还是不理解当中的原理,写这篇博客的原因,也是记录自己的学习心得和思路,供自己日后自己思考。

首先从简单的问题入手,如何写一个多线程的C++代码?

  1. #include<iostream>
  2. #include<thread>
  3.  
  4. void fun(int a){
  5. a++;
  6. }
  7.  
  8. int main(){
  9.  
  10. int a=;
  11.  
  12. std::thread t(fun,a); //创建一个线程t,t调用函数fun,a作为fun的参数,也要写到thread的构造函数当中;
    t.join(); //启动线程t,并且阻塞主线程,等到线程t运行结束后,再继续运行主线程;
  13.  
  14. std::cout<<a<<std::endl;
  15.  
  16. }

上面这段代码是最简单的多线程代码,调用thread类,并利用了thread的构造函数创建一个线程t,thread类的构造函数重载了很多,后面会继续说到。

在这里要说一下,thread类当中的两个成员函数,join()和detach()。这两个成员的作用就像上面代码的注释那样,启动新生成的线程的,但是区别在于join()函数是启动子线程而阻塞主线程,当子线程运行结束后,才会继续运行主线程。相比之下,detach()函数的作用是启动子线程,并且让子线程和主线程分离,子线程和主线程各运行各的,虽然两个线程会因为共享内存池的原因在操作系统的层面发生发生阻塞等关系,但是在代码层次上,两个线程并不存在谁阻塞谁,很可能主线程已经运行结束了,子线程还在运行。

接下来,我们要说一下类当中的成员函数如何初始化thread类的构造函数。

对于类的成员函数,我们需要给出类对象的地址:

  1. #include<iostream>
  2. #include<thread>
  3.  
  4. class A{
  5.  
  6. public:
  7.  
  8. void fun(int a,int b){
  9.  
  10. std::cout<<"this is A thread!"<<a<<std::endl;
  11. }
  12. };
  13.  
  14. int main(){
  15.  
  16. int k=;
  17.  
  18. A a;
  19.  
  20. std::thread t(&A::fun,a,k,k+);
  21. t.join();
  22.  
  23. }
  1. std::thread t(&A::fun,a,k,k+1); 这个地方就可以看出thread类的构造对于成员函数的重载了,std::thread t(函数(成员函数)地址,对象地址,成员函数的参数1,参数2,参数3...)。
    相比非成员函数,成员函数需要给出类实例化对象的地址,如果该线程是在同一类的某一成员函数当中被构造,则直接用this关键字代替即可。
  2.  
  3. 其实,我在写成员函数的多线程代码的时候,发现成员函数的需要传递的参数太多会使thread类的构造函数重载失败,我测试了一下,成员函数最多只能传递4个参数,也就说std::thread类的构造函数最多只能重载6个参数。
    这一点,我并没有找到相关文档得到证实,只是在写代码的时候发现成员函数传递参数太多,会一直编译不通过,偶然间发现这个点的,具体到底对不对,我也不是很确定。
  4.  
  5. 其次,我们要说一下加锁和解锁的问题。
    因为我们创造的每一个线程只要在一个进程内,都是共享内存池的,这样在读写数据可能会发生混乱。
    C++11提供了mutex类进行加锁和解锁。
  1. #include<iostream>
  2. #include<thread>
  3. #include<mutex>
  4.  
  5. std::mutex mut;
  6.  
  7. class A{
  8.  
  9. public:
  10.  
  11. volatile int temp;
  12.  
  13. A(){
  14. temp=;
  15. }
  16.  
  17. void fun(int num){
  18.  
  19. int count=;
  20. while(count>){
  21.  
  22. mut.lock();
  23. temp++;
  24. std::cout<<"thread_"<<num<<"...temp="<<temp<<std::endl;
  25. mut.unlock();
  26.  
  27. count--;
  28. }
  29. }
  30.  
  31. void thread_run(){
  32. std::thread t1(&A::fun,this,);
  33.  
  34. std::thread t2(&A::fun,this,);
  35.  
  36. t1.join();
  37. t2.join();
  38. }
  39. };
  40.  
  41. int main(){
  42.  
  43. A a;
  44.  
  45. a.thread_run();
  46. }
  1. 然后,我们说一下volatile关键字。
  2.  
  3. volatileconst关键很相似,都是修饰变量的,只是二者功能不一样。
  1. volatile在多线程当中经常使用,因为在某一线程多次调用某一个变量,编译器会进行优化,将该变量存放在在寄存器当中,不会每次都从内存当中读入。果然该变量同时在其他线程当中被修改,这样就会发生脏读取错误。
  2.  
  3. 而加上volatile修饰,则会提醒编译器,这个变量可能会被改变,不能存放到寄存器当中,需要每次都从内存当中读取。
  1. 最后,我们说一下join()和detach()的使用技巧。

C++11 Thread多线程的学习心得与问题的更多相关文章

  1. c++11 thread的学习

    http://www.cnblogs.com/wxquare/p/6736202.html 还没开始 留个链接 使用c++11 thread支持实现  一个生产者消费者模型 下面是一个生产者消费者问题 ...

  2. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  3. eclipse debug (调试) 学习心得

    eclipse debug (调试) 学习心得   进入debug模式:   1.设置断点   2.启动servers端的debug模式   3.运行程序,在后台遇到断点时,进入debug调试状态   ...

  4. 我的MYSQL学习心得(十七) 复制

    我的MYSQL学习心得(十七) 复制 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  5. 多线程的学习与python实现

    学习了进程与线程,现对自己的学习进行记录. 目录: 一.进程与线程的概念,以及联系与区别 二.多线程 三.python中多线程的应用 四.python实例 五.参考文献 一.进程与线程的概念.以及联系 ...

  6. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->关于spring framework中的beans

    Spring framework中的beans 1.概述 bean其实就是各个类实例化后的对象,即objects spring framework的IOC容器所管理的基本单元就是bean spring ...

  7. windows类书的学习心得(转载)

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  8. 别人的的MYSQL学习心得(十五) 日志

    我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  9. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

随机推荐

  1. YTU 2642: 填空题:类模板---求数组的最大值

    2642: 填空题:类模板---求数组的最大值 时间限制: 1 Sec  内存限制: 128 MB 提交: 646  解决: 446 题目描述   类模板---求数组的最大值    找出一个数组中的元 ...

  2. ASP.NET Core开发Docker部署

    ASP.NET Core开发Docker部署,.NET Core支持Docker 部署运行.我们将ASP.NET Core 部署在Docker 上运行. 大家可能都见识过Docker ,今天我们就详细 ...

  3. [Codeforces Round511C] Enlarge GCD

    [题目链接] https://codeforces.com/contest/1047/problem/C [算法] 首先求出n个数的最大公约数g , 将每个数除以g , 那么 , 问题就转化为在n个数 ...

  4. 洛谷 P1328 生活大爆炸版石头剪刀布 —— 模拟

    题目:https://www.luogu.org/problemnew/show/P1328 直接模拟即可. 代码如下: #include<iostream> #include<cs ...

  5. IntelliJ IDEA 缓存和索引介绍

    转自:https://www.cnblogs.com/zhanghaibinblogs/p/6722061.html IDEA 在首次加载项目的时候都会创建索引,IDEA 的缓存和索引主要是用来加快文 ...

  6. 【148】DevExpress相关控件使用

    ---------------------------------------------------------------------------------------------------- ...

  7. jQuery——表单应用(2)

    多行文本框应用之高度变化 HTML: <!--表单-多行文本框应用-高度变化--> <!DOCTYPE html> <html> <head> < ...

  8. 用Movie显示gif(2)GifView

    1,类 import android.annotation.SuppressLint; import android.content.Context; import android.content.r ...

  9. JAVA使用Ldap操作AD域

    项目上遇到的需要在集成 操作域用户的信息的功能,第一次接触ad域,因为不了解而且网上其他介绍不明确,比较费时,这里记录下. 说明: (1). 特别注意:Java操作查询域用户信息获取到的数据和域管理员 ...

  10. 1619. [HEOI2012]采花

    1619. [HEOI2012]采花 ★★☆   输入文件:1flower.in   输出文件:1flower.out   简单对比 时间限制:5 s   内存限制:128 MB [题目描述] 萧薰儿 ...