C++11 Thread多线程的学习心得与问题
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多线程的学习心得与问题的更多相关文章
- c++11 thread的学习
http://www.cnblogs.com/wxquare/p/6736202.html 还没开始 留个链接 使用c++11 thread支持实现 一个生产者消费者模型 下面是一个生产者消费者问题 ...
- 我的MYSQL学习心得(十六) 优化
我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- eclipse debug (调试) 学习心得
eclipse debug (调试) 学习心得 进入debug模式: 1.设置断点 2.启动servers端的debug模式 3.运行程序,在后台遇到断点时,进入debug调试状态 ...
- 我的MYSQL学习心得(十七) 复制
我的MYSQL学习心得(十七) 复制 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- 多线程的学习与python实现
学习了进程与线程,现对自己的学习进行记录. 目录: 一.进程与线程的概念,以及联系与区别 二.多线程 三.python中多线程的应用 四.python实例 五.参考文献 一.进程与线程的概念.以及联系 ...
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->关于spring framework中的beans
Spring framework中的beans 1.概述 bean其实就是各个类实例化后的对象,即objects spring framework的IOC容器所管理的基本单元就是bean spring ...
- windows类书的学习心得(转载)
原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...
- 别人的的MYSQL学习心得(十五) 日志
我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
随机推荐
- 【codevs2183】匹配字符串
KMP裸题 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring ...
- tf.float32 implicity
简介 | TensorFlow https://tensorflow.google.cn/programmers_guide/low_level_intro 我们来构建一个简单的计算图.最基本的指 ...
- linux下I2C驱动架构全面分析【转】
本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...
- 今晚的两道 bc
第一道题 Beautiful Palindrome Number ,简单组合计数问题,手算打表就好~大概十五分钟左右搞定[第一次 提交竟然 wa了一次 有一个小小的坑在那.... /******** ...
- LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
题目:https://loj.ac/problem/6089 对于 i <= √n ,设 f[i][j] 表示前 i 种,体积为 j 的方案数,那么 f[i][j] = ∑(1 <= k ...
- 代码中特殊的注释技术——TODO、FIXME和XXX的用处 (转载)
转自:http://blog.csdn.net/reille/article/details/7161942 作者:reille 本博客网址:http://blog.csdn.net/reille/, ...
- C#自动内存分配
一.在程序运行时由CLR管理内存分配(Memory Allocation),程序启动时,操作系统会为每一个线程申请一个独立的栈内存,用于存储方法的局部变量.参数和返回值等:CLR会为进程申请一个连续的 ...
- Ajax 知识点总结
1.AJAX的优缺点都有什么? 最大的一点是页面无刷新,用户的体验非常好.使用异步方式与服务器通信,具有更加迅速的响应能力.可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻 ...
- 自己编写的str操作函数
1.strcat() 此函数原型为 char *strcat(char *dest, const char *src). 功能为连接两个字符串,把src连接到dest后面:返回dest地址 实现如下 ...
- 区间DP UVA 11584 Partitioning by Palindromes
题目传送门 /* 题意:给一个字符串,划分成尽量少的回文串 区间DP:状态转移方程:dp[i] = min (dp[i], dp[j-1] + 1); dp[i] 表示前i个字符划分的最少回文串, 如 ...