C++11的标准库中提供了多线程库,使用时需要#include <thread>头文件,该头文件主要包含了对线程的管理类std::thread以及其他管理线程相关的类。下面是使用C++多线程库的一个简单示例:
#include <iostream>
#include <thread>
using namespace std;
void output(int i)
{
cout << i << endl;
}
int main()
{
for (int i = 0; i < 4; i++)
{
thread t(output, i);// 创建一个线程t运行output,传递给output的参数为i(t创建完成后自动启动)
t.detach();
}
getchar();
return 0;
}
这段代码的作用是:在一个for循环内,创建4个线程分别输出数字0、1、2、3,并且在每个数字的末尾输出换行符。如果是顺序执行的话,预期应输出:
0 \n 1 \n 2 \n 3 \n
实际运行一下,以下是两次运行结果:
可以看出,四个线程的执行顺序并不是按照预期输出的,以第二次输出为例,首先输出了01,并没有输出换行符;紧接着却连续输出了2个换行符。
这就涉及到多线程编程最核心的问题了:资源竞争。CPU有4核,是可以同时执行4个线程的,但是控制台却只有一个,同时只能有一个线程拥有这个唯一的控制台。将上面代码创建的四个线程进行编号:t0,t1,t2,t3,分别输出的数字:0,1,2,3。参照上图的执行结果,控制台的拥有权的转移如下:
t0拥有控制台,输出了数字0,但是其没有来的及输出换行符,控制的拥有权却转移到了t1(0)
t1完成自己的输出,t1线程完成 (1\n)
控制台拥有权转移给t0,输出换行符 (\n)
t2拥有控制台,完成输出 (2\n)
t3拥有控制台,完成输出 (3\n)
由于控制台是系统资源,这里控制台拥有权的管理是操作系统完成的。但是,假如是多个线程共享进程空间的数据,这就需要自己写代码控制,每个线程何时能够拥有共享数据进行操作。共享数据的管理以及线程间的通信,是多线程编程的两大核心。