提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、线程和多线程
线程
线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程
简单来说线程就是调度和分配的基本单位,因此引入多线程的概念自然也就是提高了调度和分配的效率,从而提高了程序的运行效率。多线程的存在能够把一个任务分解成很多小的部分,各个小部分能够同时执行,而不是只能顺序的执行,以达到节省时间的目的。对于求和,把所有数据一起相加和分段求和再相加没什么区别。
二、c++中的多线程实现
1.简介
传统的C++(C++98)中并没有引入线程这个概念。linux和unix操作系统的设计采用的是多进程,进程间的通信十分方便,同时进程之间互相有着独立的空间,不会污染其他进程的数据,天然的隔离性给程序的稳定性带来了很大的保障。而线程一直都不是linux和unix推崇的技术,甚至有传言说linus本人就非常不喜欢线程的概念。随着C++市场份额被Java、Python等语言所蚕食,为了使得C++更符合现代语言的特性,在C++11中引入了多线程与并发技术。
2.具体实现
在c++11中,使用了类对象thread即线程类来实现,需要引入头文件thread,对于一个thread类的创建对象即开始了一个线程。
使用方法如下:
thread first(函数名,参数1,参数2……);
对于没有thread的文件来说,main函数就是其唯一线程,也叫做主线程。对于包含thread的文件来说,一旦创建了一个thread对象后,即在主线程外创建了一个子线程,其立刻开始运行,与主线程没有任何关系。
但是对于一个子线程,我们并不知道其何时调度运行,何时运行结束。例如在主线程即main函数运行结束后整个程序就结束了,然而子线程并没有运行结束而被迫中止,这就达不到目的,于是引入两个函数。
①join()函数。
thread first(函数名,参数1,参数2……);
first.join();
其中join函数的功能是阻塞,作用是主线程必须等待子线程结束后才能继续进行,即同步作用。
②detach()函数
表示主线程不用等待子线程执行完毕,两者脱离关系,完全放飞自我。这个一般用在守护线程上:有时候我们需要建立一个暗中观察的线程,默默查询程序的某种状态,这种的称为守护线程。这种线程会在主线程销毁之后自动销毁。注意:C++中一个标准线程函数只能返回void,因此需要从线程中返回值往往采用传递引用的方法。
三、代码示例
在本次实例中我们使用10000000个1相加的求和的一般实现和多线程实现来对比运行效率。其中,为了检测运行时间,我们引入time头文件实现。
一般实现代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <numeric>
#include <time.h>
using namespace std;
//线程要做的事情就写在这个线程函数中
void GetSumT(vector<int>::iterator first, ve