提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一、线程和多线程
    • 线程
    • 多线程
  • 二、c++中的多线程实现
    • 1.简介
    • 2.具体实现
  • 三、代码示例
  • 四、问题

一、线程和多线程

线程

线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

多线程

简单来说线程就是调度和分配的基本单位,因此引入多线程的概念自然也就是提高了调度和分配的效率,从而提高了程序的运行效率。多线程的存在能够把一个任务分解成很多小的部分,各个小部分能够同时执行,而不是只能顺序的执行,以达到节省时间的目的。对于求和,把所有数据一起相加和分段求和再相加没什么区别。

二、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, vector<int>::iterator last, int& result)
{result = accumulate(first, last, 0); //调用C++标准库算法
}int main() //主线程
{clock_t start_time, end_time;start_time = clock();   //获取开始执行时间int result1, result2, result3, result4, result5;vector<int> largeArrays;for (int i = 1;i <= 100000000;i++){largeArrays.push_back(1);}int resultSum;GetSumT(largeArrays.begin(),largeArrays.end() , resultSum);cout << resultSum << endl;end_time = clock();     //获取结束时间double Times = (double)(end_time - start_time) / CLOCKS_PER_SEC;printf("%f seconds\n", Times);}
100000000
36.100000 seconds

多线程实现代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <numeric>
#include <time.h>
using namespace std;//线程要做的事情就写在这个线程函数中
void GetSumT(vector<int>::iterator first, vector<int>::iterator last, int& result)
{result = accumulate(first, last, 0); //调用C++标准库算法
}int main() //主线程
{clock_t start_time, end_time;start_time = clock();   //获取开始执行时间int result1, result2, result3, result4, result5;vector<int> largeArrays;for (int i = 1;i <= 100000000;i++){largeArrays.push_back(1);}thread first(GetSumT, largeArrays.begin(),largeArrays.begin() + 20000000, std::ref(result1)); //子线程1thread second(GetSumT, largeArrays.begin() + 20000000,largeArrays.begin() + 40000000, std::ref(result2)); //子线程2thread third(GetSumT, largeArrays.begin() + 40000000,largeArrays.begin() + 60000000, std::ref(result3)); //子线程3thread fouth(GetSumT, largeArrays.begin() + 60000000,largeArrays.begin() + 80000000, std::ref(result4)); //子线程4thread fifth(GetSumT, largeArrays.begin() + 80000000,largeArrays.end(), std::ref(result5)); //子线程5first.join(); //主线程要等待子线程执行完毕second.join();third.join();fouth.join();fifth.join();int resultSum = result1 + result2 + result3 + result4 + result5; //汇总各个子线程的结果cout << resultSum << endl;end_time = clock();     //获取结束时间double Times = (double)(end_time - start_time) / CLOCKS_PER_SEC;printf("%f seconds\n", Times);}
100000000
31.296000 seconds

可以看出多线程实现效率大于一般实现。

四、问题

多线程效率的确较快,但对于上一个样例,在多线程中我们使用了5个线程来跑,按理说应该是五倍的效率,然而结果却不是这样,为什么呢?
以单核cpu为例,多线程的模型如下:
其多线程的实现方式是利用cpu空闲时间来跑其他线程的任务,但是在进入其他线程时就必须消耗时间来保存上一个线程和打开下一个线程,因此多线程并不是一定效率就比顺序执行效率高。

c++多线程简单实现相关推荐

  1. javascript worker 多线程 简单示例

    javascript worker 多线程 简单示例 项目结构 主线程 index.html <!DOCTYPE html> <html lang="en"> ...

  2. Java学习笔记2 多线程简单总结

    多线程简单总结 1. 相关概念 1.1 线程与进程 进程 线程 1.2 线程调度 分时调度 抢占式调度 1.3 同步与异步 同步 异步 1.4 并发与并行 并发 并行 2. 创建线程 2.1 继承Th ...

  3. C++ 高性能计算之多线程简单基础入门教程

    C/C++ 高性能计算之多线程简单基础入门教程 比起别人的盲目罗列函数接口,鹦鹉学舌式的解释每一个输入参数和输出参数,一味求全而无重点,我的文章更侧重于入门知识的讲解,宁缺毋滥,只有一些最简单的入门用 ...

  4. 继承Thread类实现多线程简单实例

    继承Thread类实现多线程简单实例 文章目录 继承Thread类实现多线程简单实例 一.多线程的意义 二.多线程的创建 三.代码 一.多线程的意义 1.为什么要使用多线程 (a)提高用户体验或者避免 ...

  5. iOS开发值多线程简单介绍

    2019独角兽企业重金招聘Python工程师标准>>> 今天,我们就来说一下iOS多线程的问题,为什么要使用iOS多线程?因为一个应用程序在一个时间内可能有一个呗或者多任务,我们不可 ...

  6. openmp多线程简单编程

    OpenMP支持的编程语言包括C.C++和Fortran,简单的说,就是一种API,来编写多线程应用程序.通过使用简单的指令#pragma omp -就可以对程序进行多线程并行.OpenMP使得程序员 ...

  7. iOS多线程编程之多线程简单介绍(转载)

    一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过& ...

  8. iOS开发多线程篇—多线程简单介绍

    一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过& ...

  9. C++多线程简单入门(二)(Windows版)

    之前那片文章简述了如何使用C++多线程. C++多线程模拟就好像是自己在做一件事情,但是感觉不够快,就跟自己的朋友说,在自己做的这一部分的时候,你去帮我做另外一部分,那么这样就提高了效率. (点击可查 ...

最新文章

  1. java 反射机制--根据属性名获取属性值
  2. ubuntu无限卡在logo界面
  3. 高并发场景下的httpClient优化使用
  4. Qt / SIGNAL、SLOT、signals、slots、emit 关键字含义
  5. JQuery-学习笔记06【高级——JQuery事件绑定和切换】
  6. 正确入门Service Mesh:起源、发展和现状
  7. 在SAP CRM呼叫中心里创建Service Request的实现技术
  8. POJ 1286 Necklaces of Beads (Burnside定理,有限制型)
  9. javascript用window open的子窗口关闭自己并且刷新父窗口
  10. 前端遇到瓶颈怎么办?我来告诉你
  11. UVa 1400 (线段树) Ray, Pass me the dishes!
  12. 软件测试 - V模型、W模型、H模型、X模型
  13. Linux_Qt:-1: error: cannot find xxx/lib: file format not recognized
  14. QCC3020开发问题汇总(更新中。。。)
  15. IDEA工具上传项目报:Push rejected: Push to origin/master was rejected
  16. 使用AUI框架开发微信小程序
  17. 微信公众平台卡券API接口开发指南
  18. 初学盲打,免费,免安装,高颜值的在线打字练习网站
  19. 骗子改电脑配置信息兜售垃圾,怕上当进来学习一下
  20. 台式机插上耳机没有声音

热门文章

  1. Linux Docker 安装部署
  2. ros下启动robotiq-2f85电爪
  3. 还在为Android表情开发烦恼吗,快来试试Android Emoji吧
  4. 硬件工程师基础知识1
  5. 手机或者邮箱登陆 mysql查询语句
  6. 物联网控制APP入门专题(四)---使用android studio制作一个控制页面的APP框架
  7. 遍历HashMap的5种方式
  8. android动态评论功能,Android辅助权限实战之微信自动评论与点赞
  9. C++ | 你真的了解namespace吗?
  10. 汉语言文学要学计算机课程吗,汉语言文学专业学什么 主要课程有哪些