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的函数指针

C++ 并发编程 01 线程api的更多相关文章

  1. JUC 并发编程--01,线程,进程,经典卖票案例, juc的写法

    进程: 就是一个程序, 里面包含多个线程, 比如一个QQ程序 线程: 进程中最小的调度单元, 比如 QQ中的自动保存功能 并发: 多个线程操作同一资源, 抢夺一个cpu的执行片段, 快速交替 并行: ...

  2. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  3. 并发编程 01—— ThreadLocal

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  4. 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  5. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  6. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  7. Java并发编程:线程池的使用(转载)

    文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  8. [转]Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  9. 【转】Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

随机推荐

  1. hdu KiKi's K-Number 主席树

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. hdu 2444 The Accomodation of Students 判断二分图+二分匹配

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  3. spark 累加历史 + 统计全部 + 行转列

    spark 累加历史主要用到了窗口函数,而进行全部统计,则需要用到rollup函数 1  应用场景: 1.我们需要统计用户的总使用时长(累加历史) 2.前台展现页面需要对多个维度进行查询,如:产品.地 ...

  4. jar插件应用

    Gson(解析json) 作用:在servlet层中解析json 1:导入jar包 gson-2.2.4.jar 例如:Gson gson = new Gson();                  ...

  5. 简述 JPA 与 Spring Data JPA 与 Hibernate

    1.JPA是什么?以及相关概述 JPA的是 Java Persistence API 的简写,是Sun官方提出的一种ORM规范! Sun提出此规范有2个原因: 1.简化现有Java EE和Java S ...

  6. 解决IE6中img标签 图片透明

    <!--[if IE 6]> <script type="text/javascript"> function correctPNG() { for (va ...

  7. [转载]Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)

    本文主要解决一个问题,如何实现二叉树的前中后序遍历,有两个要求: 1. O(1)空间复杂度,即只能使用常数空间: 2. 二叉树的形状不能被破坏(中间过程允许改变其形状). 通常,实现二叉树的前序(pr ...

  8. POJ 3278 Catch That Cow bfs 难度:1

    http://poj.org/problem?id=3278 从n出发,向两边转移,为了不使数字无限制扩大,限制在2*k以内, 注意不能限制在k以内,否则就缺少不断使用-1得到的一些结果 #inclu ...

  9. 【MVC】MusicStore相关资料

    引言 当你对MVC的项目结构有一定了解时,那就可以开始学习一个世界级的MVC入门demo--MusicStore.学习的绝招就是把它抄一遍. 相关资料 MVC Music Store  Codeple ...

  10. easyui panel自适应浏览器宽度

    一.目标效果: 当浏览器窗口大小改变时.panel宽度始终为浏览器宽度的50%,panel高度则根据其中内容的多少而变化,横向竖向滚动条皆不出现.且不需要重新刷新浏览器或者其他js代码 兼容:chro ...