码迷,mamicode.com
首页 > 编程语言 > 详细

c++ 多线程 0

时间:2018-05-21 14:44:35      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:执行   something   切换   标识   图片   ast   数据   std   pos   

1.1 何谓并发

最简单和最基本的并发,是指两个或更多独立的活动同时发生。  (注意区别于计算机中的并发情况!!!!!!!!!!见下面)

 

1.1.1 计算机系统中的并发:是指在单个系统里同时执行多个独立的任务,而非顺序的进行一些活动

通过这个任务做一会儿,在切换到别的任务,再做一会儿的方式 ,让任务看起来是并行执行的,这种方式称为“任务的切换”,如今仍然叫做   并发。

应为 任务切换的太快 以至于感觉不到任务在何时会被挂起。 任务切换会给用户造成一种“并发的假象”。因为这种假象,当应用在任务切换的环境下和真

正并发环境下执行相比,行为还是有着微妙的不同。特别是对内存模型不正确的假设,在多线程环境中可能不会出现。

 

图1.1显示了一个计算机处理两个任务时的理想情景,每个任务被分为10个相等大小的块。在一个双核机器上,每个任务可以在各自的处理上执行。                  在单核机器上做任务切换时,每个任务的块交织进行。但中间有一小段分隔; 为实现交织进行,每次从一个任务切换到另一个时都需要切换一次上下文,切换有时间开销。切换时,操作系统必须为当前运行的任务保存CPU的状态和指令指针,计算出要切换到哪个任务,并为即将切换到的任务重新加载处理器状态。           然后,CPU可能要将新任务的指令和数据的内存载入缓存中,这会阻止CPU执行任何指令,从而造成的更多的延迟

技术分享图片

图 1.1 并发的两种方式:双核机器的真正并行 Vs. 单核机器的任务切换

技术分享图片

图 1.2 四个任务在两个核心之间的切换

 

 

技术分享图片

图 1.3 一对并发运行的进程之间的通信

 

技术分享图片

图 1.4 同一进程中的一对并发运行的线程之间的通信

 

清单 1.1 一个简单的Hello, Concurrent World程序:

#include <iostream>
#include <thread>  //①
void hello()  //②
{
  std::cout << "Hello Concurrent World\n";
}
int main()
{
  std::thread t(hello);  //③
  t.join();  //④
}

④这里调用join()的原因 这会导致调用线程(在main()中等待与std::thread对象相关联的线程,即这个例子中的t。

 

 

 

第2章 线程管理

主要内容

  • 启动新线程
  • 等待线程与分离线程
  • 线程唯一标识符

 

2.1.1 启动线程

    1 最简单的情况下,任务也会很简单,通常是无参数无返回(void-returning)的函数。这种函数在其所属线程上运行,直到函数执行完毕,线程也就结束了。

void do_some_work();
std::thread my_thread(do_some_work);

   

     2 将带有函数调用符类型的实例传入std::thread类中,替换默认的构造函数。

 class background_task{
   public:
   void operator()() const{  //这个类型重载了运算符()
      do_something();
      do_something_else();
   }
 };
background_task f;
std::thread my_thread(f);

注意 :

当把函数对象传入到线程构造函数中时,需要避免“最令人头痛的语法解析”(C++’s most vexing parse中文简介)。

如果你传递了一个临时变量,而不是一个命名的变量;C++编译器会将其解析为函数声明,而不是类型对象的定义。

例如:

std::thread my_thread(  background_task()  );

这里相当与声明了一个名为my_thread的函数,这函数带有一个参数(函数指针指向没有参数并返回background_task对象的函数),返回一个std::thread对象的函数而非启动了一个线程

使用在前面命名函数对象的方式,或使用多组括号①, 或使用新统一的初始化语法② lambda表达式也能避免这个问题  也可以避免这个问题。

如下所示:

std::thread my_thread(  ( background_task() )   );  // 1
std::thread my_thread{  background_task()  };    // 2

==============================================================

启动了线程,你需要明确是要等待线程结束(join),还是让其自主运行(detach分离式)。

如果std::thread对象销毁之前还没有做出决定,程序就会终止(std::thread的析构函数会调用std::terminate())。

因此,即便是有异常存在,也需要确保线程能够正确的加入(joined)或分离(detached)。

c++ 多线程 0

标签:执行   something   切换   标识   图片   ast   数据   std   pos   

原文地址:https://www.cnblogs.com/zhangkele/p/9066501.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!