1、夏磊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、生两个新的进程(线程)处理分割后的数据,线程直接共享内存数据,进程间的数据交换采用内存映射文件。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个
3、测试使用的数据,写到二进制文件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/ 数据缓冲区指针extern int
4、* g_pData; / 数据量大小 extern int g_nDataCount; / 信号量,用于控制排序线程的数目HANDLE hSemaphoreThread = NULL; / 事件,用于通知控制台线程排序完成HANDLE hEventSortOver = NULL; /* * 线程参数结构 */struct ThreadParam int* m_pData; / 数据缓冲区指针 int m_nLow; / 数据开始下标 int m_nHigh; / 数据截止下标;/* * 线程函数 */DWORD WINAPI threadProc( LPVOID lpParam );/* *
5、主函数 */void main( int argc, char* argv ) /作业2:进程同步机制实验生产者消费者问题 /作者:夏磊 S1048035 /指导教师:陈向群、原仓周 printf( =n ); printf( 作业2-1:多线程实现快速排序n ); printf( 学生:夏磊 S1048035 n ); printf( 指导教师:陈向群、原仓周 n ); printf( =n ); char szFileName80; / 文件名 int nTimeGap = 0; / 时间计数 HANDLE hThread = NULL; / 线程句柄 / 初始化数据缓冲区,信号量和事件
6、g_pData = new intg_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.da
7、t ); /随机初始化数据 initDataFile(szFileName); / 读取数据 while( !readFile(szFileName) ) printf( 文件%s打开失败,请重新输入文件名:, szFileName ); scanf( %s, szFileName ); / 打印提示符 printf( 多线程排序开始n ); / 准备线程参数 ThreadParam* param = new ThreadParam; param-m_pData = g_pData; param-m_nLow = 0; param-m_nHigh = g_nDataCount - 1; / 开
8、始计时 nTimeGap = GetTickCount(); / 启动线程,开始排序 WaitForSingleObject( hSemaphoreThread, INFINITE ); if( (hThread=CreateThread(NULL, 0, threadProc, param, 0, NULL) = NULL ) / 启动失败,中止程序 delete param; printf( 线程产生失败!n ); exit( GetLastError() ); WaitForSingleObject( hThread, INFINITE ); /判定hThread是否已经运行结束 / 等
9、待排序完成的消息 WaitForSingleObject( hEventSortOver, INFINITE );/判定是否排序完成 / 排序完成,停止计时 nTimeGap = GetTickCount() - nTimeGap; / 打印控制台消息 printf( 多线程排序n-共耗时%d毫秒-n, nTimeGap ); / 写回数据 strcpy( szFileName, Sorted.dat ); while( !writeFile(szFileName) ) printf( 文件%s写入失败,请重新输入文件名:, szFileName ); scanf( %s, szFileNam
10、e ); / 删除数据缓冲区 delete g_pData; printf(-n); system(pause);DWORD WINAPI threadProc( LPVOID lpParam ) DWORD dwWaitResult; / 等待结果 HANDLE hThread; / 线程句柄 / 解析参数 ThreadParam* param = (ThreadParam*)lpParam; int *pData = param-m_pData; int nLow = param-m_nLow; int nHigh = param-m_nHigh; / 若数据量已达限值以下,排序 if(
11、nHigh-nLow 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 ); goto
12、QUIT; else if( dwWaitResult = WAIT_OBJECT_0 ) if( (hThread=CreateThread(NULL, 0, threadProc, param1, 0, NULL) = NULL ) / 启动失败,中止程序 delete param; delete param1; delete param2; printf( 线程产生失败!n ); exit( GetLastError() ); WaitForSingleObject( hThread, INFINITE ); dwWaitResult = WaitForSingleObject( hSe
13、maphoreThread, 0L ); if( dwWaitResult = WAIT_TIMEOUT ) threadProc( param2 ); goto QUIT; else if( dwWaitResult = WAIT_OBJECT_0 ) if( (hThread=CreateThread(NULL, 0, threadProc, param2, 0, NULL) = NULL ) / 启动失败,中止程序 delete param; delete param1; delete param2; printf( 线程产生失败!n ); exit( GetLastError() );
14、 WaitForSingleObject( hThread, INFINITE ); QUIT: / 删除当前线程的参数 delete param; / 释放信号量 long lPrevCount; if( !ReleaseSemaphore(hSemaphoreThread, 1, &lPrevCount) | lPrevCount=g_nThreadBoundary-1 ) SetEvent( hEventSortOver ); / 退出 return 0;2)排序及读写文件辅助程序头文件:functions.h#pragma onceconst int g_nCount = 100000
15、0; / 数据缓冲区大小const int g_nThreadBoundary = 20; / 线程数阖值const int g_nBoundary = 1000; / 排序阖值/* * 初始化文件中数据 */bool initDataFile( char* szFileName );/* * 从文件中读入数据 */bool readFile( char* szFileName );/* * 将数据写入文件中 */bool writeFile( char* szFileName );/* * 打印数据 */void printData(int* d);/* * 写数据到文本文件 */void
16、writeToCharFile(char* const szFileName,int* d);/* * 数据分块算法 */int partition( int* pData, int nLow, int nHigh );int randomizedPartition( int* pData, int nLow, int nHigh );/* * 快速排序算法 */void quickSort( int* pData, int nLow, int nHigh );/* * 选择排序算法 */void selectSort( int* pData, int nLow, int nHigh );3)
17、排序及读写文件辅助程序实现:functions.cpp#include #include #include#include functions.hint* g_pData = 0; / 数据缓冲区指针int g_nDataCount = 0; / 数据量大小bool initDataFile(char* szFileName) / 打开文件 FILE* pFile = fopen( szFileName, wb ); if( pFile = NULL ) return false; int *A,i; A=new intg_nCount; srand(unsigned int)time(0);
18、/随机取种 以当前时间取种 for(i=0;ig_nCount;i+) Ai=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); return true;bool read
19、File( char* szFileName ) / 打开文件 FILE* pFile = fopen( szFileName, rb ); if( pFile = NULL ) return false; / 读取数据 g_nDataCount = fread( g_pData, sizeof(int), g_nCount, pFile ); /printf( 从二进制文件 %s 中读取了%d个数据n,szFileName, g_nDataCount ); fclose( pFile ); return true;bool writeFile( char* szFileName ) / 打开
20、文件 FILE* pFile = fopen( szFileName, w ); if( pFile = NULL ) return false; / 写入数据 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); return true;void printD
21、ata(int* d) printf(n-n); for(int i=0;ig_nCount;i+) printf(%d,di); if(i+1)%100!=0) printf( ); else printf(n); printf(n-n); void writeToCharFile(char* const szFileName,int* d) char fileName80; strcpy(fileName,szFileName); strcpy(fileName+strlen(fileName)-3,txt); FILE* pFile = fopen( fileName, w ); if(
22、 pFile = NULL ) return ; for(int i=0;i= nHigh ) return nLow; / 以第一个数为轴划分数组 int pivot = pDatanLow; int i = nLow; int j = nHigh; while( i j ) while( i=pivot ) j-; pDatai = pDataj; while( ij & pDatai= nHigh ) return; /qsort( pData, nHigh-nLow, sizeof(pData0), compare ); qsort( &(pDatanLow), nHigh-nLow+
23、1, sizeof(pData0), compare );void selectSort( int* pData, int nLow, int nHigh ) for( int i = nLow; i nHigh; i+ ) / 获取数据pDatai.nHigh中的最小数 int nMin = pDatai; int index = i; for( int j = i; j pDataj ) nMin = pDataj; index = j; / 将最小数调入已排序区 if( nMin pDatai ) pDataindex = pDatai; pDatai = nMin; 1.4.2多进程排序1)进程主程序:FileMapSort_Proc.cpp#include #include #include fileOperation.h#define OUTFILE C:Number.txt
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1