熟悉C++的人知道,在经过了13年的漫长等待后,C++标准委员会终于在2011年通过了C++史上的第二个标准。
C++0x VS C++11,傻傻分不清楚
从一开始到现在,C++大概经历了以下几个比较重要的阶段:
- 1998: ISO官方发布C++标准,俗称C++98,这是第一个C++的官方正式版本
- 2003: TC1(Technical Corrigendum 1)发布,俗称C++03, 这个版本可以当成是C++98的一个bugfix版本
- 2005:TR1(Technical Report 1)发布,TR1是一个新增加的库,增加了大约14种新的组件到C++标准中
- 2008:新C++标准(C++0x)草案发布,这个主要是以TR1的基础上进行了扩充
- 2011:C++0x标准通过
随着各种动态解释型语言的诞生,C++程序员也越来越感觉到了C++语言本身的一些局限性。以C++之父 Bjarne Stroustrup
(没错,就是下面这个仙风道骨的老头) 为代表的先贤们,也一直在不遗余力的努力着,让C++更加强大。
于是他们商量着:
要么大伙每5年来一次华山论剑?
好!果真,后来的C++大会基本上是5年一次,比如 2003年,2008年。
1998年C++标准发布后,原计划于2003年之后的几年推出新的标准,但由于没有确定具体哪一年发布,就用 0x
原来表示的是04-09年中的某一年。
等到了2009年,新的C++0x
标准却一致拖着没通过,直到2011
年才通过,名称还保持叫C++0x
:
x
表示是16进制
的字符0-f
,所以11
也是x
了。
所以说,C++0x
和C++11
,这俩就是一回事,只不过前者是个草案,而后者是正式通过的标准。
thread
以前,由于 C++98
中没有线程、锁、条件变量等这些与多线程相关的特性支持,如果需要写多线程程序,都要借助于不同平台上各自提供的 api,导致程序的跨平台移植性较差,经常要用一大堆的 #ifdef WIN32
类似的宏来区分不同的平台,这样写代码的姿势很难看。
现在好了,使用 C++11
可以编写跨平台的多线程程序了,而且相比原来的 pthread
写法,代码更简洁优美。
今天从 thread
开始,介绍下 C++11
带来的一系列新特性。
1 |
|
上面是 thread
的四种构造方式:
(1) 最简单,最常用的方式,直接传入一个普通函数。
(2) 变参模版方式,如果函数为类的成员函数,第一个参数是对象本身,后面的参数按函数调用时的顺序传入。注意,引用传递参数的话实参用 ref(arg)
包装。
(3) bind
方式,传入一个 std::function
对象,同样地,如果是类成员变量的话,第一个参数是对象本身。
(4) lambda
方式,是比较常用的方式(先留个坑,以后再细述)。
thread 对象
- 不可被拷贝构造。
- 可以 `move` 方式构造,
thread th(std::move(x));
之后,新构造的th
拥有原先x
的执行对象,x
不再代表执行对象。 - 可被
joinable
的thread
对象必须在他们销毁之前被主线程join
或者将其设置为detach
。
thread 方法
1.operator =
如果当前对象不可 joinable
,将获取右值的执行对象,同时,右值将不再代表执行对象;
如果当前对象可被 joinable
,则 terminate()
报错。
1 | thread th; |
2.get_id()
如果当前对象不可 joinable
,返回默认构造线程的id(0x0)
;
如果当前对象可被 joinable
,则返回当前线程的 id
。
3.joinable()
检测线程是否 joinable
。当且仅当 thread
代表某个执行对象时,它才是 joinable
的。下列条件下,属于 不可 joinable
:
a. 默认构造函数构造出来。对 thread th;
而言,th
不代表任何 thread
执行对象。
b. 被作为参数给 std::move
调用。
c. 已经调用了 join
或 detach
函数。
4.swap(x)
交换当前线程和 x 的状态、执行对象等。