C语言实现多线程的归并排序

问题

​ 利用多线程实现归并排序。归并排序是分治算法的代表,适合改写为多线程。

构造数据

​ 数据规模为 2 ∗ 1 0 6 2*10^6 2∗106,整数。 a r r a y _ l e n g t h = 2 ∗ 1 0 6 array\_length = 2*10^6 array_length=2∗106

    srand((int)time(NULL));for (int i = 0; i < array_length; ++i) {a[i] = rand();}

计时

​ 利用 &lt; s y s / t i m e . h &gt; &lt;sys/time.h&gt; <sys/time.h>内部提供的 g e t n u m o f d a y ( ) getnumofday() getnumofday()函数,可以精确到微妙级别,但我最后输出是毫秒级别,所以需要转换单位。代码如下:

struct timeval tbegin, tend;gettimeofday(&tbegin, NULL);int arg[2];arg[0] = 0;arg[1] = array_length;pthread_t  tid;numofThread = 1;pthread_create(&tid, NULL, merge_sort, arg);pthread_join(tid, NULL);gettimeofday(&tend, NULL);if (flag == 1) {printf("The number of thread that I use : %d\n", maxThreadNumber);     }

归并排序

​ 我需要控制好线程的使用个数,因此要统计当前正在运行的线程个数。为了避免潜在的bug,我并没有用到多少指针的东西,基本都是全局数组全局变量。归并排序其实有两个函数, m e r g e _ s o r t merge\_sort merge_sort函数是递归实现分治的基础。我在该函数的单线程版本上进行了些许改动。

​ 代码如下:

void merge_sort(void* arg){int *argu = (int*)arg;int left = argu[0];int right = argu[1];int mid = (left + right) >> 1;int arg1[2];int arg2[2];arg1[0] = left;arg1[1] = mid;arg2[0] = mid + 1;arg2[1] = right;if (left >= right) {return;}pthread_t t2;pthread_t t1;if (numofThread == maxThreadNumber) {flag = 1;}if (numofThread < maxThreadNumber) {numofThread += 1; pthread_create(&t1, NULL, merge_sort, arg1);pthread_join(t1, NULL); pthread_exit(NULL);numofThread -= 1;}else {merge_sort(arg1);}if (numofThread < maxThreadNumber) {numofThread += 1;pthread_create(&t2, NULL, merge_sort, arg2); pthread_join(t2, NULL);pthread_exit(NULL);numofThread -= 1;}else {merge_sort(arg2);}merge(left, right);}

完整代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#define DEBUG 0
#define array_length 2000000int a[array_length+5];
int numofThread = 0;
int maxThreadNumber = 21;
int flag = 0;void merge(int left, int right){int mid = (left + right) >> 1;int size1 = mid - left + 1;int size2 = right - mid;int t1[size1];int t2[size2];memcpy(t1, a+left, sizeof(int) * (mid-left+1));memcpy(t2, a+mid+1, sizeof(int) * (right-mid));int i = 0, j = 0;int k = left;while (i < size1 && j < size2) {if (t1[i] <= t2[j]) {a[k] = t1[i];i++;}else {a[k] = t2[j];j++;}k++;}while (i < size1) {a[k] = t1[i];k++;i++;}while (j < size2) {a[k] = t2[j];j++;k++;}
}void merge_sort(void* arg){int *argu = (int*)arg;int left = argu[0];int right = argu[1];int mid = (left + right) >> 1;int arg1[2];int arg2[2];arg1[0] = left;arg1[1] = mid;arg2[0] = mid + 1;arg2[1] = right;if (left >= right) {return;}pthread_t t2;pthread_t t1;if (numofThread == maxThreadNumber) {flag = 1;}if (numofThread < maxThreadNumber) {numofThread += 1; pthread_create(&t1, NULL, merge_sort, arg1);pthread_join(t1, NULL); pthread_exit(NULL);numofThread -= 1;}else {merge_sort(arg1);}if (numofThread < maxThreadNumber) {numofThread += 1;pthread_create(&t2, NULL, merge_sort, arg2); pthread_join(t2, NULL);pthread_exit(NULL);numofThread -= 1;}else {merge_sort(arg2);}merge(left, right);}void createData(){srand((int)time(NULL));for (int i = 0; i < array_length; ++i) {a[i] = rand();}
}int main(){createData();struct timeval tbegin, tend;gettimeofday(&tbegin, NULL);int arg[2];arg[0] = 0;arg[1] = array_length;pthread_t  tid;numofThread = 1;pthread_create(&tid, NULL, merge_sort, arg);pthread_join(tid, NULL);gettimeofday(&tend, NULL);if (flag == 1) {printf("The number of thread that I use : %d\n", maxThreadNumber);     }printf("The running time is %d millisecond\n",(tend.tv_usec - tbegin.tv_usec)/1000);#if DEBUG == 1for (int i = 0; i < array_length; ++i) {printf("%d\n",a[i]);}
#endifreturn 0;
}

性能分析

​ 下面比较各种线程数量,我的程序的运行效果。





​ 从这4个不同的线程数量可以对比看出,线程数越多,程序运行时间是越短的。单线程运行效率最低,多线程每次线程数翻倍,运行时间大大缩短。而且并不是只缩短一半,缩短幅度大大提高。

总结

​ 归并排序并不难,改写为多线程版本花费了不少时间在调试代码上。说明我对多线程的掌握还不算到位。但是通过这次练习,我有了更深刻的了解。

C语言实现多线程的归并排序相关推荐

  1. c语言线程按顺序,C语言实现多线程排序

    作者提出了相当明确的实验目标: 归并排序 多线程 但作者给出的关于归并排序的说明却不是很到位,另外,讲解顺序也稍不合理. 作者应该首先将归并排序的算法核心提取出来,可以先做一个无多线程版本的伪代码或简 ...

  2. 线程使用 c语言,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

  3. C语言 带比较器的归并排序

    1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int DataType; 5 6 //比较器 7 int myc ...

  4. 用c语言写一个两线程程序,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

  5. c语言停止线程,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

  6. 数据结构源码笔记(C语言):二路归并排序

    //实现二路归并排序算法#include<stdio.h> #include<malloc.h> #define MAXE 20 //线性表中最多元素个数typedef int ...

  7. c语言多线程游戏,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

  8. 多线程c语言,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

  9. c语言创建线程函数怎么使用方法,如何用C语言实现多线程

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...

最新文章

  1. 《数学之美》第26章 维特比和他的维特比算法
  2. JS模式:jq中简单的模式--》采摘自js设计(tomxu_version)
  3. 210106阶段三 文件I/O
  4. mysql galera 安装_MySQL Galera 集群的安装过程
  5. 1688推广工具_全面了解1688数字营销
  6. python polar函数_Python可视化很简单,可是你会吗?python绘制饼图、极线图和气泡图,让我来教教你吧,一文教会!!!...
  7. QGIS中坐标偏移处理
  8. vs2015运行项目时出现“编译器失败,错误代码为 1”的解决方案
  9. Win11掉帧严重是怎么回事?Win11玩游戏掉帧的解决方法
  10. 爬取飞猪IP免费代理练习
  11. 第3章 如何赢得客户
  12. 时间窗口(Time Windows)
  13. 华为鲲鹏计算机考试时间,华为鲲鹏认证考试中心落地我院信息工程系
  14. OGRE CG教程 (三): 渐隐效果
  15. Mybatis根据经度、纬度查询距离最近一个位置(Mysql )
  16. 婚宴座位图html5,婚宴座位图模版欣赏【婚礼纪】
  17. 宝马 OR 奥迪?NONONO,还得看我Li Auto,新款六座SUV强势来袭
  18. 电偶极子场强分布与电偶极矩的引进_物理量引进_电磁学
  19. 计算机术语中ict表示是什么意思,ICT是什么工作
  20. 抢鲜看:微信、支付宝、高德地图在Apple Watch上是酱紫玩啊!

热门文章

  1. 关于STM32利用TIM+PWM+DMA控制WS2812
  2. Apache Hadoop集群设置示例(带虚拟机)
  3. 可视化搭建平台的参考网格线设计
  4. 【计算机视觉】:(3)全景图像拼接
  5. 计算机应用基础的操作,计算机应用基础操作(1)
  6. 一步步带你了解分布式数据库的架构演变之路!
  7. C++ 内联函数/宏/outo/for/nullptr
  8. NAT以及基本配置(静态配置)
  9. C#操作Word模板文件 替换并重新生成
  10. WRKY转录因子通过促进GhMKK2介导的类黄酮生物合成调节棉花对尖孢镰刀菌的抗性