为什么使用并发
主要原因有两个:
- 分离关注点。通过将相关的代码与无关的代码分离,可以使得程序更容易理解和测试。
- 性能。有两种方式提高性能,一是将单个任务分成几部分,各自并行运行从而降低总运行时间,一个线程执行算法的一部分,另一个线程执行另一部分,这叫任务并行;第二种是每个线程在不同的数据部分上执行相同的操作,称为数据并行。
什么时候不用并发
不使用并发的唯一原因就是收益比不上成本。使用并发的代码一般难以理解,所以编写和维护需要花大量时间;其次线程本身生成、启动、调度也都需要系统资源和时间,如果并发的收益弥补不了这些成本那还是算了。
入门
从一个普通单线程程序入手:
#include <iostream>
int main()
{
std::cout << "Hello World" << std::endl;
return 0;
}
改为多线程版:
#include <iostream>
#include <thread> //1
void print() //2
{
std::cout << "Hello World" << std::endl;
}
int main()
{
std::thread t(print); //3
t.join(); //4
return 0;
}
讲一下代码中的改动:
- 引入了新的头文件,管理线程的函数和类都在中声明,但是保护共享数据的函数和类在其他文件中声明;
- 每个线程都要有初始函数,就像一个程序的初始线程是main,刚开始就要从main执行。新线程的初始函数就是print,它第一次从print执行,在3处由thread对象的构造函数指定;
- 程序启动了一个全新的线程,将线程数量一分为二——main和print;
- 新线程启动后初始线程会自顾自的继续执行,有可能先于线程结束直接返回终止程序,join的作用在这体现。
这里就可以看出实现一个多线程比普通线程多做了大量工作,上面这个例子就满足之前讲的不用并发。