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

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

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

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

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

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

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

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

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

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

#include<iostream>
#include<thread> class A{ public: void fun(int a,int b){ std::cout<<"this is A thread!"<<a<<std::endl;
}
}; int main(){ int k=; A a; std::thread t(&A::fun,a,k,k+);
t.join(); }
std::thread t(&A::fun,a,k,k+1);  这个地方就可以看出thread类的构造对于成员函数的重载了,std::thread t(函数(成员函数)地址,对象地址,成员函数的参数1,参数2,参数3...)。
相比非成员函数,成员函数需要给出类实例化对象的地址,如果该线程是在同一类的某一成员函数当中被构造,则直接用this关键字代替即可。 其实,我在写成员函数的多线程代码的时候,发现成员函数的需要传递的参数太多会使thread类的构造函数重载失败,我测试了一下,成员函数最多只能传递4个参数,也就说std::thread类的构造函数最多只能重载6个参数。
这一点,我并没有找到相关文档得到证实,只是在写代码的时候发现成员函数传递参数太多,会一直编译不通过,偶然间发现这个点的,具体到底对不对,我也不是很确定。 其次,我们要说一下加锁和解锁的问题。
因为我们创造的每一个线程只要在一个进程内,都是共享内存池的,这样在读写数据可能会发生混乱。
C++11提供了mutex类进行加锁和解锁。
#include<iostream>
#include<thread>
#include<mutex> std::mutex mut; class A{ public: volatile int temp; A(){
temp=;
} void fun(int num){ int count=;
while(count>){ mut.lock();
temp++;
std::cout<<"thread_"<<num<<"...temp="<<temp<<std::endl;
mut.unlock(); count--;
}
} void thread_run(){
std::thread t1(&A::fun,this,); std::thread t2(&A::fun,this,); t1.join();
t2.join();
}
}; int main(){ A a; a.thread_run();
}
然后,我们说一下volatile关键字。

volatile和const关键很相似,都是修饰变量的,只是二者功能不一样。
volatile在多线程当中经常使用,因为在某一线程多次调用某一个变量,编译器会进行优化,将该变量存放在在寄存器当中,不会每次都从内存当中读入。果然该变量同时在其他线程当中被修改,这样就会发生脏读取错误。

而加上volatile修饰,则会提醒编译器,这个变量可能会被改变,不能存放到寄存器当中,需要每次都从内存当中读取。
最后,我们说一下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. HDU 5475An easy problem 离线set/线段树

    An easy problem Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. shell如何查看单个或多个文件的行数或总行数

    shell如何查看单个或多个文件的行数或总行数_百度经验 https://jingyan.baidu.com/article/cbf0e500b8470f2eab28937d.html 单个文件   ...

  3. SICP习题练习

    练习1.6 new-if的三个参数会先被执行,这样就会无限循环下去 练习1.7 (define (sqrt-iter last-guess guess x) (if (good-enough? las ...

  4. 【CSU 1079】树上的查询

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1079 现有一棵有N个顶点的树,顶点的标号分别为1, 2, …, N.对于每个形如a b k的询问, ...

  5. bzoj 4337 树的同构

    4337: BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树 ...

  6. 打印二叉树中距离根节点为k的所有节点

    package tree; public class Printnodesatkdistancefromroot { /** * Given a root of a tree, and an inte ...

  7. 使用Java实现图像分割

    为减少动画制作过程中的IO操作,我们可以使用连续动画来改善动画播放效率.如果我们对图像中的每张小图像单独分割成独立的文件,那么当每次要使用这些小图像的时候,我们都得从文件中读取图像信息. 实际上我们可 ...

  8. 7. ExtJS.form中msgTarget

    转自:https://www.cnblogs.com/guafuli/articles/msgtarget_values.html Ext表单提示方式:msgTarget:有4中方式:qtip,tit ...

  9. Redis Jedsi使用方法

    JedisPoolConfig:用于配置Jedis连接池的配置 JedisPool:使用连接池获取Jedis连接 Jedis:实际与Redis进行一系列的操作 代码示例: public void de ...

  10. bzoj 1426: 收集邮票【期望dp】

    我太菜了,看的hzwer的blog才懂 大概是设f[i]表示已经拥有了i张邮票后期望还要买的邮票数,这个转移比较简单是f[i]=f[i]*(i/n)+f[i+1]*((n-i)/n)+1 然后设g[i ...