C语言实现多线程的归并排序
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();}
计时
利用 < s y s / t i m e . h > <sys/time.h> <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语言实现多线程的归并排序相关推荐
- c语言线程按顺序,C语言实现多线程排序
作者提出了相当明确的实验目标: 归并排序 多线程 但作者给出的关于归并排序的说明却不是很到位,另外,讲解顺序也稍不合理. 作者应该首先将归并排序的算法核心提取出来,可以先做一个无多线程版本的伪代码或简 ...
- 线程使用 c语言,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
- C语言 带比较器的归并排序
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int DataType; 5 6 //比较器 7 int myc ...
- 用c语言写一个两线程程序,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
- c语言停止线程,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
- 数据结构源码笔记(C语言):二路归并排序
//实现二路归并排序算法#include<stdio.h> #include<malloc.h> #define MAXE 20 //线性表中最多元素个数typedef int ...
- c语言多线程游戏,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
- 多线程c语言,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
- c语言创建线程函数怎么使用方法,如何用C语言实现多线程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Windows操作系统,C语言实现多线程: #include #include DWORD APIENTRY ThreadOne ( LPVOID thr ...
最新文章
- 《数学之美》第26章 维特比和他的维特比算法
- JS模式:jq中简单的模式--》采摘自js设计(tomxu_version)
- 210106阶段三 文件I/O
- mysql galera 安装_MySQL Galera 集群的安装过程
- 1688推广工具_全面了解1688数字营销
- python polar函数_Python可视化很简单,可是你会吗?python绘制饼图、极线图和气泡图,让我来教教你吧,一文教会!!!...
- QGIS中坐标偏移处理
- vs2015运行项目时出现“编译器失败,错误代码为 1”的解决方案
- Win11掉帧严重是怎么回事?Win11玩游戏掉帧的解决方法
- 爬取飞猪IP免费代理练习
- 第3章 如何赢得客户
- 时间窗口(Time Windows)
- 华为鲲鹏计算机考试时间,华为鲲鹏认证考试中心落地我院信息工程系
- OGRE CG教程 (三): 渐隐效果
- Mybatis根据经度、纬度查询距离最近一个位置(Mysql )
- 婚宴座位图html5,婚宴座位图模版欣赏【婚礼纪】
- 宝马 OR 奥迪?NONONO,还得看我Li Auto,新款六座SUV强势来袭
- 电偶极子场强分布与电偶极矩的引进_物理量引进_电磁学
- 计算机术语中ict表示是什么意思,ICT是什么工作
- 抢鲜看:微信、支付宝、高德地图在Apple Watch上是酱紫玩啊!