www.27111.com并发编程

  将来芯片创造,借使突破不断 5nm 极限,则 CPU
性能的晋级,或许会借助于三维集成技术,将多少个 CPU
核集成在一块,使得多核系统进一步常见。

  在此以前的 C++ 八线程,一是受限于平台,多借助于封装好的 APIs
来成功,例如:POSIX threads,Windows threads
等;二是受限于单核系统,本质上都是“伪多线程”:通过线程调度,使得单核系统开展义务的切换,形成二十四线程的假象。

  新的 C++11
标准,在语言层面上落到实处了多线程,其库中提供了有关组件,使得跨平台编写四线程cpp 程序成为大概,最终可以在多核系统中贯彻真正的并行统计

1  并发 (concurrency)

1.1 并发与互为

 
计算机中的并发,指的是在单一系统中,同时举行两个独立的移位。对于多核系统,它们在同样时刻举行的运动,则称之为并行

 
通俗的明亮:当有两个人都在边吃饭边看电视机时,对于一个人而言,吃饭和看电视就是现身,对于三个人而言,他们在同等时刻举行的位移,可称为并行。

 1) 单核的职分切换 (task switching)

  www.27111.com 1

 2) 双核的并行执行 (parallel execution)

   www.27111.com 2

 1.2 线程与经过

 
如果将进程好比一套房子,那么住在房子里的人,其从事的各个活动
(比如,厨房做饭,客厅吃饭,卧室看电视机),就是一个个的线程。以往又搬来一个人,则当两个人都在房子里,做着各自的活动时,程序便由在此以前的单线程变为了多线程

  有的房间 (比如客厅)
多人都得以而且进出,那代表着进程中某些内存空间是共享的,逐个线程都可以运用那一个共享内存。有的房间
(比如厕所)
五次只好容纳一个人,先进去的把门锁上,后到的人见状锁,就在外围等候,直到先进去的人把锁打开,那就是“互斥核
(mutex)

 
在应用程序中,具体应用到出现编程的,一是多进度并发,二是多线程并发,如下图:   

www.27111.com 3       
www.27111.com 4    

          (1) 多进程并发                     (2) 二十四线程并发

 

2  程序示例

  完毕三二十四线程必要 1) 头文件
<thread>   2) 单独的线程函数
threadFunc()   3)线程对象 thread t(threadFunc)   4)等待线程
join()

#include <thread>
#include <iostream>

void threadFunc()
{
    std::cout << "This is a thread!" << std::endl;
}

int main()
{
    std::thread t(threadFunc);
    t.join();

    std::cout << "This is main program!" << std::endl;

    return 0;
}

  输出结果为:

This is a thread!
This is main program!

   当使用 t.detach() 来代替
t.join() 时,主线程 main 不会等待新线程 t(threadFunc),只会独自运行到程序截止。

 

3  职分代替线程

3.1  七个难题

1) 线程耗尽 (exhaustion)

 软件线程是一种简单的资源,当开创的线程数量多于系统所可以提供的,一个要命
std::system_error 就会抛出,程序便会为止。

2) 线程超额 (oversubscription)

 当等待运行的线程 (ready-to-run) 多于系统硬件线程 (hardware threads)
时,线程调度器会为各类软件线程在硬件线程上分红时间片
(time-slice)。若一个线程的时刻片截止,另一个线程的时刻片刚起头时,上下文的切换
(context switch) 就会被实施。对于多核系统,当线程从一个 CPU
被切换来另一个 CPU 中时
,会招致很大的资源消耗。

3.2  基于职分 (task-based)

  基于线程编程
(thread-based),必须手动管理方面的多少个难题,增添了编程的难度。

  基于职务编程 (task-based),通过 std::async,可将难点交由
C++标准库处理,简化了程序。

  1)  头文件 <future> 

  2) 单独的职分函数 taskFunc1 和
taskFunc2 

  3) 异步职分目的 auto fut1 =
std::async(taskFunc1) 

  4) 获取职责函数再次回到值 fut1.get()

#include <iostream>
#include <thread>
#include <future>

std::string taskFunc1()
{
    std::string str = "This is task1";
    return str;
}

std::string taskFunc2()
{
    std::string str = " and task2";
    return str;
}

int main()
{
    auto fut1 = std::async(taskFunc1);
    auto fut2 = std::async(taskFunc2);

    std::cout << fut1.get() + fut2.get() << std::endl << "This is main program" << std::endl;

    return 0;
}

   输出结果为:

This is task1 and task2
This is main program

 

小结:

 1) thread-based programming needs manual management of thread
exhaustion, oversubscription, load balancing, and adaptation to new
platforms.

 2) task-based programming handles most of these issues via
www.27111.com,std::async with the default launch policy

 

参考资料:

  <C++ Concurrency in Action> chapter 1

  <Effecctive Modern C++>  chapter 7

发表评论

电子邮件地址不会被公开。 必填项已用*标注