高校后勤管理平台:一个多线程快速排序的程序调试

来源:百度文库 编辑:杭州交通信息网 时间:2024/05/05 19:01:14
在加入多线程前检验没有问题,但加入多线程后结果就不正确了,请问问题出在哪里?(我对多线程的同步/互斥不熟悉,估计问题出在这里)

#include <afxwin.h>
#include "stdafx.h"

using namespace std;

HANDLE hSemaphore;

template <class Item>
struct SortParam // 排序函数参数: data为待排数据的数组指针 num为数据的个数 sCount是最大并发线程数 Threshold是线程分割的阈值
{
Item* data;
int num;
int sCount;
int Threshold;
};

template <class Item> // 函数模板,Item是待排的数据类型
UINT MultiThreadQuickSort ( LPVOID pParam ) // 多线程快速排序算法,参数为pParam指向的SortParam结构
{
// 将传递过来的pParam所指向的参数正确读出
SortParam<Item>* pPara=(SortParam<Item>*) pParam;
Item* data=pPara->data;
int num=pPara->num;
int sCount=pPara->sCount;
int Threshold=pPara->Threshold;

if (num<=1)
return 0;
int i=0, j=num-1;
int pivot=data[0];
while(i<j)
{
while(data[j]>pivot&&(i<j))
j--;
if (i<j)
{
data[i]=data[j];
i++;
}
while(data[i]<=pivot&&(i<j))
i++;
if(i<j)
{
data[j]=data[i];
j--;
}
}
data[i]=pivot;
j=num-i-1;
SortParam<Item>* pNewSort1=new SortParam<Item>;
pNewSort1->data=data;
pNewSort1->num=i;
pNewSort1->sCount=sCount;
pNewSort1->Threshold=Threshold;
SortParam<Item>* pNewSort2=new SortParam<Item>;
pNewSort2->data=data+i+1;
pNewSort2->num=j;
pNewSort2->sCount=sCount;
pNewSort2->Threshold=Threshold;
if(i>=Threshold)
{
if (WaitForSingleObject(hSemaphore, INFINITE)==WAIT_OBJECT_0)
{
AfxBeginThread(MultiThreadQuickSort<Item>,pNewSort1);
ReleaseSemaphore(hSemaphore, 1, NULL);
}
}
else
{
MultiThreadQuickSort<Item> (pNewSort1);
}
if(j>=Threshold)
{
if (WaitForSingleObject(hSemaphore, INFINITE)==WAIT_OBJECT_0)
{
AfxBeginThread(MultiThreadQuickSort<Item>,pNewSort2);
ReleaseSemaphore(hSemaphore, 1, NULL);
}
}
else
{
MultiThreadQuickSort<Item> (pNewSort2);
}
return 0;
}

void main ()
{
CFile f;
f.Open("test.txt",CFile::modeRead);
UCHAR buff[65536];
int count=0;
while(f.Read(buff+count,1))
{
count++;
}
SortParam<UCHAR> * p=new SortParam<UCHAR>;
p->data=buff;
p->num=65536;
p->sCount=20;
p->Threshold=1000;
hSemaphore = CreateSemaphore(NULL,20,20,NULL); // 创建线程同步使用的信号量
MultiThreadQuickSort<UCHAR>(p);
CFile g;
g.Open("result.txt", CFile::modeWrite|CFile::modeCreate);
for(int i=0;i<count; i++)
{
g.Write(buff+i,1);
}
f.Close();
g.Close();
}

问题在于没有进行同步,主函数在排序完成前就退出了。

用WaitForSingleObject以及WaitForMultipleObjects进行同步。

改动代码如下。

#include <afxwin.h>
#include "stdafx.h"

using namespace std;

HANDLE hSemaphore;

template <class Item>
struct SortParam // 排序函数参数: data为待排数据的数组指针 num为数据的个数 sCount是最大并发线程数 Threshold是线程分割的阈值
{
Item* data;
int num;
int sCount;
int Threshold;
};

template <class Item> // 函数模板,Item是待排的数据类型
UINT MultiThreadQuickSort ( LPVOID pParam ) // 多线程快速排序算法,参数为pParam指向的SortParam结构
{
HANDLE h1,h2; // <---加入这行,对两个线程进行监控
// 将传递过来的pParam所指向的参数正确读出
SortParam<Item>* pPara=(SortParam<Item>*) pParam;
Item* data=pPara->data;
int num=pPara->num;
int sCount=pPara->sCount;
int Threshold=pPara->Threshold;

if (num<=1)
return 0;
int i=0, j=num-1;
int pivot=data[0];
while(i<j)
{
while(data[j]>pivot&&(i<j))
j--;
if (i<j)
{
data[i]=data[j];
i++;
}
while(data[i]<=pivot&&(i<j))
i++;
if(i<j)
{
data[j]=data[i];
j--;
}
}
data[i]=pivot;
j=num-i-1;
SortParam<Item>* pNewSort1=new SortParam<Item>;
pNewSort1->data=data;
pNewSort1->num=i;
pNewSort1->sCount=sCount;
pNewSort1->Threshold=Threshold;
SortParam<Item>* pNewSort2=new SortParam<Item>;
pNewSort2->data=data+i+1;
pNewSort2->num=j;
pNewSort2->sCount=sCount;
pNewSort2->Threshold=Threshold;
if(i>=Threshold)
{
if (WaitForSingleObject(hSemaphore, INFINITE)==WAIT_OBJECT_0) <---这里的INFINITE改为0,不然就锁死了
{
AfxBeginThread(MultiThreadQuickSort<Item>,pNewSort1);
// ReleaseSemaphore(hSemaphore, 1, NULL); <---这句要删掉,线程没完成怎么能释放信号量呢?
}
}
else
{
MultiThreadQuickSort<Item> (pNewSort1);
}
if(j>=Threshold)
{
if (WaitForSingleObject(hSemaphore, INFINITE)==WAIT_OBJECT_0) <---INFINITE改为0,不然会死锁
{
AfxBeginThread(MultiThreadQuickSort<Item>,pNewSort2);
// ReleaseSemaphore(hSemaphore, 1, NULL); <---和上面一样,这句也要删掉
}
}
else
{
MultiThreadQuickSort<Item> (pNewSort2);
}
WaitForSingleObject(h1,INFINITE);//<---加上这两句,等待两线程的完成
WaitForSingleObject(h2,INFINITE);
ReleaseSemaphore(hSemaphore,2,NULL); //<---加上这句,释放信号量
return 0;
}

void main ()
{
CFile f;
f.Open("test.txt",CFile::modeRead);
UCHAR buff[65536];
int count=0;
while(f.Read(buff+count,1))
{
count++;
}
SortParam<UCHAR> * p=new SortParam<UCHAR>;
p->data=buff;
p->num=65536;
p->sCount=20;
p->Threshold=1000;
hSemaphore = CreateSemaphore(NULL,20,20,NULL); // 创建线程同步使用的信号量
MultiThreadQuickSort<UCHAR>(p);
CFile g;
g.Open("result.txt", CFile::modeWrite|CFile::modeCreate);
for(int i=0;i<count; i++)
{
g.Write(buff+i,1);
}
f.Close();
g.Close();
}

看不懂,学习中ing