提示:本文的所有代码由C语言实现,经过测试,C++的多线程操作也会遇到同样的问题。多线程库用的是pthread.h,操作系统是win10。windows下的pthread.h安装,可以参考下这篇文章:vs2017如何配置pthread环境

文章目录

  • 前言
  • 一、多线程代码
    • 1.带有返回值的多线程代码
    • 2.结果展示
  • 二、问题修复
    • 1.修改子线程调用方法
    • 2.结果展示
  • 总结

前言

最近因为工作需要,调研了一下C语言的多线程使用。在测试常用功能的时候遇到这么一个诡异的问题,通过结构体获取返回值的时候,多线程操作变慢了。经过一天的努力,最终解决了这个问题。以下是对该问题的记录。


一、多线程代码

1.带有返回值的多线程代码

下面代码包括生成一个5行1000万列的随机数组,然后分别使用多线程的和单线程的方法对每一行进行求和。其中多线程的参数是一个结构体,包括要求和的数组和一个sum返回值。

#include <stdio.h>
#include <time.h>
#include <pthread.h>  //定义随机数组的行和列
#define ROW   5
#define COL 10000000//获得随机数组
int ** getRandom()
{printf("生成%dX%d的随机数组\n", ROW, COL);int  **r;r = (int **)malloc(ROW * sizeof(int));for (int i = 0; i < ROW; i++) {r[i] = (int *)malloc(COL * sizeof(int));}srand((unsigned)time(NULL));for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; ++j){r[i][j] = rand();}}printf("随机数组生成完毕\n\n");return r;
}//定义传入线程的结构体
typedef struct TagValue
{int *arr;long long sum;
} Tag;//子线程调用求和方法
void* threadSum(void *d) {Tag *v = (Tag*)d;int *arr = v->arr;for (int i = 0; i < COL; i++) {v->sum += *(arr + i);}
}//多线程主方法
void  testThreadTime(int **r) {//计算多线程运行时间clock_t start, end;//传入参数结构体Tag res[ROW];//线程id号pthread_t ths[ROW];//记时开始start = clock();for (int i = 0; i < ROW; i++) {res[i].arr = r[i];res[i].sum = 0;//开启子线程int ret_thrd1 = pthread_create(&ths[i], NULL, (void *)&threadSum, (void *)&res[i]);// 线程创建成功,返回0,失败返回失败号if (ret_thrd1 != 0) {printf("子线程%d创建失败\n",i);}else {printf("子线程%d创建成功\n",i);}}//增加join函数,使主线程等待子线程都结束for (int i = 0; i < ROW; i++) {pthread_join(ths[i], NULL);}//打印返回值printf("多线程的执行结果是:\n");for (int i = 0; i < ROW; i++) {printf("%lld\n", res[i].sum);}printf("主线程执行完毕\n");//计时结束end = clock();printf("Time Used: %f\n\n", difftime(end, start));
}//非多线程对照方法
void  testNoThreadTime(int **r) {clock_t start, end;//int **r = getRandom();long long res[ROW];memset(res, 0, ROW * sizeof(long long));start = clock();for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {res[i] += r[i][j];}}end = clock();printf("对照组执行结果是:\n");for (int i = 0; i < ROW; i++) {printf("%lld\n", res[i]);}printf("Time Used: %f\n\n", difftime(end, start));
}int main() {int **r = getRandom();testThreadTime(r); testNoThreadTime(r);  getchar();return 0;
}

2.结果展示


可见多线程不但没有减少计算时间,反而增加了很多。

二、问题修复

1.修改子线程调用方法

出现问题是threadSum函数里的这句代码v->sum += *(arr + i),这句代码对主线程里声明的地址内容进行了大量的修改操作。按照下面方式修改,声明临时变量sum,求和在临时变量sum中进行,只需进行简单的修改,多线程变慢的问题就解决了

void* threadSum(void *d) {Tag *v = (Tag*)d;int *arr =v->arr;long long sum = 0;for (int i = 0; i < COL; i++) {sum+=*(arr + i);}v->sum = sum;
}

2.结果展示


修改之后,多线程已经可以正常提升计算效率了。

总结

在C/C++的多线程使用过程中,一定要注意在子线程中对传入地址的写操作。频繁的跨线程写操作,会带来效率的大幅降低。

记录一个使C/C++多线程无法加速计算的问题相关推荐

  1. 记录一个C++多线程的坑

    记录一个C++多线程的坑 VS2019报错 解决方案: 错误代码 修改方案: 写在最后,发牢骚 VS2019报错 1>C:\Program Files (x86)\Microsoft Visua ...

  2. 复习Java第二个项目仿QQ聊天系统 03(两种通信类、登录以及注册功能完善) Java面试题并发编程相关知识生活【记录一个咸鱼大学生三个月的奋进生活】025

    记录一个咸鱼大学生三个月的奋进生活025 复习Java(仿QQ聊天系统03两种通信类.登录以及注册功能完善) TcpSocket类(与服务器进行通信) Server类(服务器类) TcpMessage ...

  3. 写一个使两个整数进行交换的方法(不能使用临时变量) 【前端每日一题-27】...

    写一个使两个整数进行交换的方法(不能使用临时变量) 这道题是一个比较有意思的题,记录于此. var a=10; var b=20;...不用临时变量让a和b交换console.log(a); cons ...

  4. Operating System-Thread(5)弹出式线程使单线程代码多线程化会产生那些有关问题

    Operating System-Thread(5)弹出式线程&&使单线程代码多线程化会产生那些问题 本文主要内容 弹出式线程(Pop-up threads) 使单线程代码多线程化会产 ...

  5. 复习Java第一个项目学生信息管理系统 04(权限管理和动态挂菜单功能) python简单爬数据实例Java面试题三次握手和四次挥手生活【记录一个咸鱼大学生三个月的奋进生活】016

    记录一个咸鱼大学生三个月的奋进生活016 复习Java(学生信息管理系统04权限管理和动态挂菜单功能) 改写MainFrame的构造方法 新增LoginFrame的验证登录是否成功的代码 新增Logi ...

  6. 一个轻巧高效的多线程c++stream风格异步日志(一)

    一个轻巧高效的多线程c++stream风格异步日志 一个轻巧高效的多线程c++stream风格异步日志 前言 功能需求 性能需求 Logger实现 LogStream类 Logger类 LogStre ...

  7. 复习Java小球游戏代码分享Java面试题MySQL中常用的锁生活【记录一个咸鱼大学生三个月的奋进生活】021

    记录一个咸鱼大学生三个月的奋进生活021 复习Java小球游戏 游戏界面的代码 小球运动线程的代码 运行游戏的代码 运行结果 代码分享 学习Java面试题(MySQL中常用的锁) 照片分享 复习Jav ...

  8. 复习Java第二个项目仿QQ聊天系统 01(界面部分) Java面试题Redis的过期策略和内存淘汰策略生活【记录一个咸鱼大学生三个月的奋进生活】023

    记录一个咸鱼大学生三个月的奋进生活023 复习Java(仿QQ聊天系统01界面部分) 设置背景(ImgPanel)类 登录界面(LoginFrame)类 注册界面(RegisterFrame)类 好友 ...

  9. 把一个质量为M0 的物体加速到 时间慢100倍 需要多大能量

    洛伦兹系数  γ = 100: 运动时候的质量  M = γM0 速度   v = c*sqrt(1-1/γ2) E = 1/2 * m0c2  *γ* (1-1/γ2) 如果一个60kg 的人想要加 ...

最新文章

  1. 哪个websocket库与Node.js一起使用? [关闭]
  2. loj #143. 质数判定
  3. 该页面仅以HTML格式保存_第七节:框架搭建之页面静态化的剖析
  4. LeetCode 151. 翻转字符串里的单词(栈)
  5. SpringMVC核心——视图渲染(包含视图解析)问题
  6. c语言如何运行txt文件,如何使用EOF在C中运行文本文件?
  7. 手写一切(updating...)
  8. html5hover鼠标悬停,不使用hover外部CSS样式实现hover鼠标悬停改变样式
  9. java虚拟机带键盘安卓版下载。_jvm1.5官方下载
  10. 汇率战争下的人民币走势
  11. python判断图片相似度_图像检索系列——利用 Python 检测图像相似度!
  12. git中提交显示!rejected,如何解决?
  13. unity3d 坦克大战实战
  14. 5G套餐资费会越来越便宜,但需注意“限速机制”
  15. python tkinter.Text 高级用法 -- 设计功能齐全的文本编辑器
  16. 算法设计题3.16-栈和队列-第3章-《数据结构习题集》-严蔚敏吴伟民版
  17. 【23届秋招总结系列】一个普本23届小学弟的秋招总结,上岸金山云开发(云计算方向)
  18. 互联网协会与IDGVC发布Web2.0 100(附名单)
  19. 段永平-雪球专刊·段永平投资问答录(上册 商业逻辑篇)(二)
  20. Python报错:NameError: name 'reduce' is not defined 和 reduce()函数介绍

热门文章

  1. 计算机系个性策划书,《计算机系12月心理活动策划书》.doc
  2. 2021年5月信息系统项目管理师真题基础知识1~32题
  3. 差分 + 差分矩阵 (差分)
  4. 【金猿信创展】数新网络——国内云数智操作系统信创领导者
  5. 【Pytorch的优化器总结归纳】
  6. 一个包含30行代码的Python项目:如何在您最喜欢的Twitcher流式传输时设置SMS通知...
  7. 为大地增添一抹绿色植树节公益活动
  8. matlab相关,来自一个初学者的收藏
  9. 成功股权激励方案的特点
  10. 内部基因决定拼购品质,苏宁拼购或将成为行业发展新标杆