C++ 并发编程 01 线程api
1.使用多线程的好处: 提高性能,分离关注点
2. 多线程所在头文件 <thread>
3. 使用线程方式为std::thread(functioncall),如:
#include <iostream>
#include <thread> void hello()
{
std::cout<<"Hello Concurrent World\n";
} int main()
{
std::thread t(hello);
t.join();
}
4. thread api:
- constructor
使用一个函数,或者是一个callable object来初始化一个thread 对象。实际就是associate一个thread对象和一个thread of execution,便能够开启一个线程了。当然你也可以声明一个thread对象而不对其associate,这个时候有些方法就不能执行。
注意:
(1)如果和thread 对象绑定的execution函数有参数,那么也是通过associate时,一同传入的。如果thread对象绑定的execution函数有返回值,那么可以通过传入一个引用,或者指针将返回值,传递出来。当然对于返回值,后面章节会有其他解决办法。
(2)一旦一个thread对象,绑定了execution函数,在其线程终止之前必须要对其进行处理。不能使其在开启这个thread的进程结束之后,还在运行。否则系统会调用std::thread::terminate()出错。解决办法有两个A。join声明由创建它的程序来回收。detach表示将其run in background,最后系统回收。
- join
join兼有等待某个thread结束与回收其资源的作用。某个associate的对象,只能join一次,可以通过函数std::thread::joinable来判定。
- detach 调用后线程将在后台运行run in background,该线程与这个进程内的其他线程无关了。但是若这个线程的进程结束,这个线程也会被终止。
注意: 某个associate了execution function的对象,也只能detach一次。可以用joinable来判定。return,exit都是结束进程。UNIX结束线程可以用thread_cancel
#include <thread>
#include <Windows.h> void do_something(int& i)
{
++i;
} struct func
{
int& i; func(int& i_):i(i_){} void operator()()
{
for(unsigned j=;j<;++j)
{
do_something(i);
}
}
}; void oops()
{
int some_local_state=;
func my_func(some_local_state);
std::thread my_thread(my_func);
my_thread.detach();
} int main()
{ oops(); //::Sleep(10 * 1000);
}
上述示例中,oops启动了一个线程,并调用detach()在后台运行,其实一个耗时线程,进行100万次累加操作,但是主线程main()可能已经结束退出,所以该程序可能会出现错误。
- std::move
这个函数可以显式转移线程的拥有权,线程对象不能赋值,但是可以转移。相当于,转移那个associate关系。被move的thread 对象就没有绑定的execution function了。
- hardware_concurrency
static方法,返回这台主机的硬件并发数,即内核数量。
- get_id()/ this_thread::get_id()
返回线程的id,返回的id类型是std::thread::id类型的。
注意:可以相互比较大小,如果两个大小相同,他们就是相同的thread。
必须要associate execution function的thread object才有有意义的数字thread id。返回没有associate的,会显示没有绑定,但不会终止程序。
5. 线程的启动
在定义thread创建的时候即启动线程
6. 线程的委托对象
函数/ Callable对象实例(即带重载operator()的对象class或struct)
如下面代码中的CallableStruct结构体即为Callable对象,
struct CallableStruct
{
int& i; func(int& i_):i(i_){} void operator()()
{
for(unsigned j=;j<;++j)
{
std::cout<<j<<std::endl;
}
}
}; int some_local_state=;
CallableStruct my_CallableStruct(some_local_state);
std::thread my_thread(my_CallableStruct);
my_thread.detach();
使用Callable对象实例初始化线程时推荐使用以下方式:
std::thread my_thread((CallableStruct())); // 多加一层括号将对象的实例化给括起来
std::thread my_thread{CallableStruct()}; //C++ 11 初始化语法
std::thread my_thread(CallableStruct()); // 错误,意思变成了指向一个无参数,返回值为CallableStruct的函数指针
最新文章
- Jquery 轮播图简易框架
- springmvc请求接收参数的几种方法
- 总结Controller向View传值的方式(转)
- Ubuntu下类似于Total Commander的两个工具
- Peer certificate cannot be authenticated with known CA certificates.
- uva 10453 - Make Palindrome(dp, 记录路径)
- Web 服务器上的请求筛选被配置为拒绝该请求,因为查询字符串过长
- c&;c++函数的参数和返回值的传递终结版
- WPFX名称空间
- C primer plus 读书笔记第八章
- Oracle SQL篇(一)null值之初体验
- 对于COM对象使用ComPtr代替传统指针
- Visual Studio 2014
- scrapy setting 备注
- U盘发现器
- mui的上拉加载更多 下拉刷新 自己封装的demo
- Linux运维第二课----Linux发展史、环境准备
- 01-html介绍和head标签
- 通过apicloud实现的混合开发App的Demo
- win10 64位,家庭版,C++,ini配置说明
热门文章
- JS localStorage 存储变量
- php while循环
- 使用 shinydashboard
- 炫酷的CSS3抖动样式:CSS Shake
- 移动前端兼容性笔记 - 安卓2.x 自带原生浏览器箭头问题
- javascript中new Date()会存在偏差一小时的bug
- POJ 3087 Shuffle&#39;m Up bfs
- UVALive 5903 Piece it together 二分匹配,拆点 难度:1
- 在JavaScript中进行文件处理,第二部分:文件读取
- jmeter4.0---自带录制功能录制脚本