夏磊S1048035作业3多进程线程实现快速排序.docx

上传人:b****5 文档编号:3280504 上传时间:2022-11-21 格式:DOCX 页数:38 大小:355.59KB
下载 相关 举报
夏磊S1048035作业3多进程线程实现快速排序.docx_第1页
第1页 / 共38页
夏磊S1048035作业3多进程线程实现快速排序.docx_第2页
第2页 / 共38页
夏磊S1048035作业3多进程线程实现快速排序.docx_第3页
第3页 / 共38页
夏磊S1048035作业3多进程线程实现快速排序.docx_第4页
第4页 / 共38页
夏磊S1048035作业3多进程线程实现快速排序.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

夏磊S1048035作业3多进程线程实现快速排序.docx

《夏磊S1048035作业3多进程线程实现快速排序.docx》由会员分享,可在线阅读,更多相关《夏磊S1048035作业3多进程线程实现快速排序.docx(38页珍藏版)》请在冰豆网上搜索。

夏磊S1048035作业3多进程线程实现快速排序.docx

夏磊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=pivot)

{

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"

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1