展示一下我的代码,采用多线程的快速排序,有很多值得学习的地方哦~!

jbz001 2010-07-24 11:19:59
有些地方可能写的不够完美,大家可以尽管提出修改方案。
此源代码下载地址:http://download.csdn.net/source/2571258


#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>

#define NUM 10000*1000 //设置数组中的数据量,设定为1000万

HANDLE hMutex;
int count=0; //记录创建线程的总数量

struct ThreadSortData //定义为多线程函数传递的参数
{
int *p; //指向数组的指针
int i; //数组段的起始序号
int j; //数组段的结束序号
};

DWORD WINAPI ThreadQuickSort(LPVOID lpParam) //多线程快速排序
{
int i=((ThreadSortData *)lpParam)->i; //直接使用参数太麻烦,重新申请短变量并赋值
int j=((ThreadSortData *)lpParam)->j;
int *num=((ThreadSortData *)lpParam)->p;
count++;

int start=i; //记录起始序号
int end=j; //记录结束序号
int key=num[i]; //保存关键值

while(i<j) //排序
{
while(i<j && num[j]>=key)
{
j--;
}
num[i]=num[j];

while(i<j && num[i]<=key)
{
i++;
}
num[j]=num[i];
}
num[i]=key;

HANDLE hThread1;
HANDLE hThread2;
if((i-start)>1) //如果本段数组关键字的左端至少有两个数据,那么继续排序
{
ThreadSortData *pData1=new ThreadSortData;
pData1->i=start;
pData1->j=i-1;
pData1->p=num;
hThread1=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData1,0,NULL);
}

if((end-j)>1) //如果本段数组关键字的右端至少有两个数据,那么继续排序
{
ThreadSortData *pData2=new ThreadSortData;
pData2->i=i+1;
pData2->j=end;
pData2->p=num;
hThread2=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData2,0,NULL);
}

WaitForSingleObject(hThread1,INFINITE); //子线程执行完毕后主线程再继续运行
WaitForSingleObject(hThread2,INFINITE); //子线程执行完毕后主线程再继续运行
CloseHandle(hThread1);
CloseHandle(hThread2);

delete[] lpParam; //释放动态内存

return TRUE;
}

void main()
{
srand(GetTickCount());

int *num=new int[NUM];
int temp;
for(int i=0;i<NUM;i++)
{
temp=rand()+rand();
num[i]=(temp<<16)+rand()+rand(); //为了保证数组中所有的值在-2^31到2^31-1之间均匀分布
}
printf("\n");

ThreadSortData *pData=new ThreadSortData; //申请的动态内存在创建的线程中释放
pData->p=num;
pData->i=0;
pData->j=NUM-1;

HANDLE hThread;
hMutex=CreateMutex(NULL,FALSE,NULL);
int time=GetTickCount(); //线程开始时计数
hThread=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData,0,NULL);
WaitForSingleObject(hThread,INFINITE); //子线程执行完毕后主线程再继续运行
time=GetTickCount()-time; //线程结束时所花费的时间
CloseHandle(hThread); //关闭线程句柄

/* for(i=0;i<NUM;i++) //输出数据
{
printf("%d ",num[i]);
}
printf("\n");*/

printf("一共创建了%d个线程\n",count); //输出总线程数
printf("一共花费了%d毫秒\n",time); //输出总线程数

delete[] num;
}
...全文
1017 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
cuticle 2011-10-02
  • 打赏
  • 举报
回复
代码很垃圾哦~~首先快排可以扩展为非递归的,其次再非递归情况下你要考虑你的CPU核数来建立相应的线程,再者,WINDOWS API中的创建线程效率很低哦,你可以试试openMP中的#pragma omp parallel sections哦。。。
jbz001 2011-07-27
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 lhsundriver 的回复:]

什么烂代码,调了半天,靠!
[/Quote]

你自己不会C或者C++吧?
lhsundriver 2011-07-27
  • 打赏
  • 举报
回复
什么烂代码,调了半天,靠!
WilliamCPT 2010-09-01
  • 打赏
  • 举报
回复
挺下,正在学多线程。看了收益良多、、、
wjb_yd 2010-07-26
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 jackyjkchen 的回复:]
楼主若想提高效率,那就不要创建这么多线程,快速排序没有磁盘io,纯粹的cpu计算,单线程就能占满一个内核,所以几个内核创建几个线程足以,多了的话调度开销反而抵消了性能提升
[/Quote]

这个是正解
konta 2010-07-26
  • 打赏
  • 举报
回复
围观~
bobo364 2010-07-26
  • 打赏
  • 举报
回复
楼主写的挺好,这里好多东西本来就是写着玩玩,实际意义不大的,在接点分,早日升星
jackyjkchen 2010-07-26
  • 打赏
  • 举报
回复
楼主若想提高效率,那就不要创建这么多线程,快速排序没有磁盘io,纯粹的cpu计算,单线程就能占满一个内核,所以几个内核创建几个线程足以,多了的话调度开销反而抵消了性能提升
lin_style 2010-07-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 blackboyofsnp 的回复:]

Visual C++从2005起内置openMP支持,支持多线程操作容易了。
[/Quote]

搜了下openMP,好象是个好东西哦。可以免出线程管理的透明。。
Q446512799 2010-07-26
  • 打赏
  • 举报
回复
围观~~~~~~~~
jbz001 2010-07-26
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 canshui 的回复:]

弱弱的问一句mark.啥意思
[/Quote]
mark是积分的意思。
另外,这段代码仍然有很多问题。
比如多余出来的HANDLE hMutex;
还有线程池的问题,经过测试一个进程最多只能创建2011个线程。
而我这个远远超过了2011个线程。
nkluckyfire 2010-07-26
  • 打赏
  • 举报
回复
可惜了
写了这么多 实际应用不大啊
cnlm2 2010-07-26
  • 打赏
  • 举报
回复
这程序写的牛,接分!!!!!!!!!!!!!!!!!
youdaping777 2010-07-26
  • 打赏
  • 举报
回复
路过,学习,学习!
  • 打赏
  • 举报
回复
楼主,加个线程池吧,不考虑加线程等开销,确实可以快不少。
canshui 2010-07-25
  • 打赏
  • 举报
回复
弱弱的问一句mark.啥意思
canshui 2010-07-25
  • 打赏
  • 举报
回复
悲剧于数据结构的学习的飘过……

收藏啦,咱慢慢研究去……呜呜……
AAA20090987 2010-07-25
  • 打赏
  • 举报
回复
mark...
jbz001 2010-07-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cattycat 的回复:]

没看出来你的mutex有什么用。
还好快速排序一次划分后,分两个区间继续排序,所以两个区间不会对数据写冲突,不用同步。
此外,当数据非常大的时候就有问题了,最坏的情况已经有序的情况要创建很多线程。
还有一点,windows一个进程最多可以创建2048个线程,当然你把线程栈大小设小点的话,可以创建多一些。
[/Quote]
mutex是以前做其他用处的,忘了删了。
我运行这个程序时,创建的线程远远超过了2048个。也许处于运行状态的线程最多只有2048个吧。
coxfilur_2008 2010-07-25
  • 打赏
  • 举报
回复
mark.
加载更多回复(14)

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧