夏磊S1048035作业3多进程线程实现快速排序.docx
- 文档编号:3280504
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:38
- 大小:355.59KB
夏磊S1048035作业3多进程线程实现快速排序.docx
《夏磊S1048035作业3多进程线程实现快速排序.docx》由会员分享,可在线阅读,更多相关《夏磊S1048035作业3多进程线程实现快速排序.docx(38页珍藏版)》请在冰豆网上搜索。
夏磊S1048035作业3多进程线程实现快速排序
操作系统报告
实验3--多进程(线程)实现快速排序
***********
学号:
S*******
班级:
2010级秋季班
指导教师:
陈向群、原仓周
1设计思路及主要代码分析
1.1实验目的
使用多进程(线程)方式,实现快速排序,体会多进程(线程)的实际应用中的优势。
1.2实验要求
在Windows环境下,编写一个多进程(线程)进行快速排序的程序,使用的是产生1,000,000个随机数的文件。
要求说明你的程序运行的系统资源配置,给出测试结果并对测试程序和结果做出说明。
1.3设计思路
1.3.1程序流程图
1)多线程排序流程图
2)多进程排序流程图
1.3.2设计说明
1)每次数据分割后产生两个新的进程(线程)处理分割后的数据,线程直接共享内存数据,进程间的数据交换采用内存映射文件。
2)每个进程(线程)处理的数据小于1000以后不再分割(控制产生的进程在20个左右)。
3)利用一些技巧使分割尽可能均匀:
比较第一个、最后一个、中间一个,三者中中间值作为分割值。
1.3.3程序结构设计
1)可运行程序文件
程序主要为2个主运行程序和1个子进程排序程序。
2个主运行程序分别为:
线程排序程序FileMapSort_Thread.exe和进程排序程序FileMapSort_Proc.exe。
1个子进程排序程序为:
qsort_proc.exe。
2)测试数据
程序中使用随机函数初始化1,000,000个测试使用的数据,写到二进制文件Unsorted.dat中,然后读取到内存或内存映射文件,以便多线程(进程)排序,排序后将结果写到二进制文件Sorted.dat中。
出于IO的性能考虑使用了二进制文件读写,另外,为了便于查看,排序前的数据和排序后的数据分别保存在了对应的Unsorted.txt和Sorted.txt中。
3)时间计算
由于数据量较大,时间较长,使用GetTickCount()即可。
1.4程序代码
1.4.1多线程排序
1)主程序代码:
FileMapSort_Thread.cpp
#include
#include
#include"functions.h"
//数据缓冲区指针
externint*g_pData;
//数据量大小
externintg_nDataCount;
//信号量,用于控制排序线程的数目
HANDLEhSemaphoreThread=NULL;
//事件,用于通知控制台线程排序完成
HANDLEhEventSortOver=NULL;
/**
*线程参数结构
*/
structThreadParam
{
int*m_pData;//数据缓冲区指针
intm_nLow;//数据开始下标
intm_nHigh;//数据截止下标
};
/**
*线程函数
*/
DWORDWINAPIthreadProc(LPVOIDlpParam);
/**
*主函数
*/
voidmain(intargc,char**argv)
{
//作业2:
进程同步机制实验——生产者消费者问题
//作者:
夏磊S1048035
//指导教师:
陈向群、原仓周
printf("==================================================================\n");
printf("作业2-1:
多线程实现快速排序\n");
printf("学生:
夏磊S1048035\n");
printf("指导教师:
陈向群、原仓周\n");
printf("==================================================================\n");
charszFileName[80];//文件名
intnTimeGap=0;//时间计数
HANDLEhThread=NULL;//线程句柄
//初始化数据缓冲区,信号量和事件
g_pData=newint[g_nCount];
hSemaphoreThread=CreateSemaphore(NULL,g_nThreadBoundary,g_nThreadBoundary,NULL);
hEventSortOver=CreateEvent(NULL,false,false,NULL);
if(hSemaphoreThread==NULL||hEventSortOver==NULL)
{
printf("信号量初始化失败!
\n");
exit(GetLastError());
}
strcpy(szFileName,"Unsorted.dat");
//随机初始化数据
initDataFile(szFileName);
//读取数据
while(!
readFile(szFileName))
{
printf("文件%s打开失败,请重新输入文件名:
",szFileName);
scanf("%s",szFileName);
}
//打印提示符
printf("……多线程排序开始……\n");
//准备线程参数
ThreadParam*param=newThreadParam;
param->m_pData=g_pData;
param->m_nLow=0;
param->m_nHigh=g_nDataCount-1;
//开始计时
nTimeGap=GetTickCount();
//启动线程,开始排序
WaitForSingleObject(hSemaphoreThread,INFINITE);
if((hThread=CreateThread(NULL,0,threadProc,param,0,NULL))==NULL)
{
//启动失败,中止程序
deleteparam;
printf("线程产生失败!
\n");
exit(GetLastError());
}
WaitForSingleObject(hThread,INFINITE);//判定hThread是否已经运行结束
//等待排序完成的消息
WaitForSingleObject(hEventSortOver,INFINITE);//判定是否排序完成
//排序完成,停止计时
nTimeGap=GetTickCount()-nTimeGap;
//打印控制台消息
printf("……多线程排序……\n------共耗时%d毫秒------\n",nTimeGap);
//写回数据
strcpy(szFileName,"Sorted.dat");
while(!
writeFile(szFileName))
{
printf("文件%s写入失败,请重新输入文件名:
",szFileName);
scanf("%s",szFileName);
}
//删除数据缓冲区
delete[]g_pData;
printf("------------------------------------------------------\n");
system("pause");
}
DWORDWINAPIthreadProc(LPVOIDlpParam)
{
DWORDdwWaitResult;//等待结果
HANDLEhThread;//线程句柄
//解析参数
ThreadParam*param=(ThreadParam*)lpParam;
int*pData=param->m_pData;
intnLow=param->m_nLow;
intnHigh=param->m_nHigh;
//若数据量已达限值以下,排序
if(nHigh-nLow { //将数据排序 quickSort(pData,nLow,nHigh); //退出 gotoQUIT; } //否则,将数据分块 else { //将数据分块 //intnMid=partition(pData,nLow,nHigh); intnMid=randomizedPartition(pData,nLow,nHigh); //准备新线程的参数 ThreadParam*param1=newThreadParam; ThreadParam*param2=newThreadParam; param1->m_pData=pData; param1->m_nLow=nLow; param1->m_nHigh=nMid; param2->m_pData=pData; param2->m_nLow=nMid+1; param2->m_nHigh=nHigh; //启动两个新线程 dwWaitResult=WaitForSingleObject(hSemaphoreThread,0L); if(dwWaitResult==WAIT_TIMEOUT) { threadProc(param1); threadProc(param2); gotoQUIT; } elseif(dwWaitResult==WAIT_OBJECT_0) { if((hThread=CreateThread(NULL,0,threadProc,param1,0,NULL))==NULL) { //启动失败,中止程序 deleteparam; deleteparam1; deleteparam2; printf("线程产生失败! \n"); exit(GetLastError()); } WaitForSingleObject(hThread,INFINITE); } dwWaitResult=WaitForSingleObject(hSemaphoreThread,0L); if(dwWaitResult==WAIT_TIMEOUT) { threadProc(param2); gotoQUIT; } elseif(dwWaitResult==WAIT_OBJECT_0) { if((hThread=CreateThread(NULL,0,threadProc,param2,0,NULL))==NULL) { //启动失败,中止程序 deleteparam; deleteparam1; deleteparam2; printf("线程产生失败! \n"); exit(GetLastError()); } WaitForSingleObject(hThread,INFINITE); } } QUIT: //删除当前线程的参数 deleteparam; //释放信号量 longlPrevCount; if(! ReleaseSemaphore(hSemaphoreThread,1,&lPrevCount)||lPrevCount==g_nThreadBoundary-1) { SetEvent(hEventSortOver); } //退出 return0; } 2)排序及读写文件辅助程序头文件: functions.h #pragmaonce constintg_nCount=1000000;//数据缓冲区大小 constintg_nThreadBoundary=20;//线程数阖值 constintg_nBoundary=1000;//排序阖值 /** *初始化文件中数据 */ boolinitDataFile(char*szFileName); /** *从文件中读入数据 */ boolreadFile(char*szFileName); /** *将数据写入文件中 */ boolwriteFile(char*szFileName); /** *打印数据 */ voidprintData(int*d); /** *写数据到文本文件 */ voidwriteToCharFile(char*constszFileName,int*d); /** *数据分块算法 */ intpartition(int*pData,intnLow,intnHigh); intrandomizedPartition(int*pData,intnLow,intnHigh); /** *快速排序算法 */ voidquickSort(int*pData,intnLow,intnHigh); /** *选择排序算法 */ voidselectSort(int*pData,intnLow,intnHigh); 3)排序及读写文件辅助程序实现: functions.cpp #include #include #include #include"functions.h" int*g_pData=0;//数据缓冲区指针 intg_nDataCount=0;//数据量大小 boolinitDataFile(char*szFileName) { //打开文件 FILE*pFile=fopen(szFileName,"wb"); if(pFile==NULL) { returnfalse; } int*A,i; A=newint[g_nCount]; srand((unsignedint)time(0));//随机取种以当前时间取种 for(i=0;i A[i]=rand();//随机生成a数组 //写入数据 g_nDataCount=fwrite(A,sizeof(int),g_nCount,pFile); //printf("在二进制文件%s中初始化了%d个数据\n",szFileName,g_nDataCount); printf("随机初始化了%d个数据\n",g_nDataCount); fclose(pFile); //printData(A); writeToCharFile(szFileName,A); returntrue; } boolreadFile(char*szFileName) { //打开文件 FILE*pFile=fopen(szFileName,"rb"); if(pFile==NULL) { returnfalse; } //读取数据 g_nDataCount=fread(g_pData,sizeof(int),g_nCount,pFile); //printf("从二进制文件%s中读取了%d个数据\n",szFileName,g_nDataCount); fclose(pFile); returntrue; } boolwriteFile(char*szFileName) { //打开文件 FILE*pFile=fopen(szFileName,"w"); if(pFile==NULL) { returnfalse; } //写入数据 g_nDataCount=fwrite(g_pData,sizeof(int),g_nCount,pFile); //printf("向二进制文件%s写入了%d个数据\n",szFileName,g_nDataCount); fclose(pFile); //printData(g_pData); writeToCharFile(szFileName,g_pData); returntrue; } voidprintData(int*d){ printf("\n---------------------------------------------------------\n"); for(inti=0;i { printf("%d",d[i]); if((i+1)%100! =0){ printf(""); }else{ printf("\n"); } } printf("\n---------------------------------------------------------\n"); } voidwriteToCharFile(char*constszFileName,int*d) { charfileName[80]; strcpy(fileName,szFileName); strcpy(fileName+strlen(fileName)-3,"txt"); FILE*pFile=fopen(fileName,"w"); if(pFile==NULL) { return; } for(inti=0;i { charstr[20]; itoa(d[i],str,10); fwrite(str,1,strlen(str),pFile); if((i+1)%100! =0){ fwrite("",1,strlen(""),pFile); }else{ fwrite("\n",1,strlen("\n"),pFile); } } fclose(pFile); printf("可查看数据的文本文件%s\n",fileName); } intpartition(int*pData,intnLow,intnHigh) { //算法结束 if(nLow>=nHigh) { returnnLow; } //以第一个数为轴划分数组 intpivot=pData[nLow]; inti=nLow; intj=nHigh; while(i { while(i { j--; } pData[i]=pData[j]; while(i { i++; } pData[j]=pData[i]; } pData[i]=pivot; //返回轴位置 returni; } intrandomizedPartition(int*pData,intnLow,intnHigh) { //inti=(int)(((rand()*(nHigh-nLow))%10000)/10000); inti=(int)((nLow+nHigh)/2); inttemp; temp=pData[i]; pData[i]=pData[nLow]; pData[nLow]=temp; returnpartition(pData,nLow,nHigh); } intcompare(constvoid*ele1,constvoid*ele2) { return*(int*)ele1-*(int*)ele2; } voidquickSort(int*pData,intnLow,intnHigh) { //算法结束 if(nLow>=nHigh) { return; } //qsort(pData,nHigh-nLow,sizeof(pData[0]),compare); qsort(&(pData[nLow]),nHigh-nLow+1,sizeof(pData[0]),compare); } voidselectSort(int*pData,intnLow,intnHigh) { for(inti=nLow;i { //获取数据pData[i...nHigh]中的最小数 intnMin=pData[i]; intindex=i; for(intj=i;j { if(nMin>pData[j]) { nMin=pData[j]; index=j; } } //将最小数调入已排序区 if(nMin { pData[index]=pData[i]; pData[i]=nMin; } } } 1.4.2多进程排序 1)进程主程序: FileMapSort_Proc.cpp #include #include #include"fileOperation.h" #defineOUTFILE"C: \\Number.txt"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 夏磊 S1048035 作业 进程 线程 实现 快速 排序
![提示](https://static.bdocx.com/images/bang_tan.gif)