01.简介
1.并发
1.1 定义
并发就是两个或以上的活动同时进行。计算机中的并发是指在单个系统中同时执行多个独立的任务。
1.2 并发的方式
1.多进程并发
将应用程序分为多个独立的进程同时运行。就像同时进行网页游览和文字处理一样。独立的进程之间可以依靠通信渠道(信号,套接字,文件,管道等)传递信息。
这种方式的缺点是:进程间的通信十分复杂,运行多个进程需要固定的开销:需要时间启动进程,操作系统需要资源管理进程。
优点是更容易编写安全的并发代码。
2.多线程并发
在单进程中运行多个线程。进程中的所有线程都共享地址空间,并且能访问到大部分数据(全局变量仍然是全局的,指针、对象的引用或数据可以在线程之间传递)。虽然共享内存,但同一数据的内存地址在不同的进程中不同。
共享内存的代价:如果多个线程访问数据,必须保证每个线程访问的数据一致,这就需要大量的线程通信工作。
1.3 为什么使用并发
1.分离关注点
2.性能
收益小于成本时,就不适用并发。
2.入门
2.1 C++并发入门
C++多线程程序和其他的C++程序差不多。唯一的区别在于某些函数可以并发运行,所以需要确保共享数据在访问时安全的。
#include <iostream>
int main(){
std::cout<<"hello world!\n";
}
上述程序所做的就是将字符串写入标准输出流。
#include <iostream>
#include <thread> //1
void hello(){ //2
std::cout<<"hello concurrent world\n";
}
int main(){
std::thread t(hello); //3
t.join(); /4
}
上述程序在1处增加了头文件,管理线程的函数和类在
打印信息的代码移动到了一个新的独立的函数。这是因为每个线程都要有一个initial function,新线程的执行从此处开始。
对于应用,初始线程的initial function是main(),但是对于其他的线程,initial function由std::thread对象的构造函数指定。例如对象t的参数,hello()作为initial function
上述程序使用了两个线程完成信息的输出,一个是主线程,从main()开始。一个是新的线程,由hello()开始。在新的线程启动后,主线程继续执行。如果主线程不等待新线程结束,就会运行到main()函数结束,这个过程有可能发生在新线程运行之前。所以需要在main()中调用join()函数,这会使得创建线程等待std::thread对象创建的线程。