临界区的互斥控制
2009-11-01 20:31:15 来源:WEB开发网每一个线程都要使用下面这个函数进行输出,而且只有一个显示器,产生多个线程竞争对控制台的使用权。
//*****************************临界区***************************************
//
void PrintResult(long* Array, int iLength, const char* HeadStr)
//***************************************************************************
{
WaitForSingleObject(evtPrint, INFINITE); //等待事件有信号
//EnterCriticalSection(&csPrint); //标记有线程进入临界区
//WaitForSingleObject(mtxPrint, INFINITE); //等待互斥量空置(没有线程拥有它)
int i;
printf("%s: ", HeadStr);
for (i=0; i<iLength-1; i++)
{
printf("%d,", Array[i]);
Sleep(100); //延时(可以去掉)
/*只是使得多线程对临界区访问的问题比较容易看得到
如果你把临界控制的语句注释掉,输出就会变得很凌乱,各个排序的结果会
分插间隔着输出,如果不延时就不容易看到这种不对临界区控制的结果
*/
}
printf("%d\n", Array[i]);
SetEvent(evtPrint); //把事件信号量恢复,变为有信号
//LeaveCriticalSection(&csPrint); //标记线程离开临界区
//ReleaseMutex(mtxPrint); //释放对互斥量的占有
}
三、排序思想与具体算法
3.1 冒泡排序思想(升序,降序同理,后面的算法一样都是升序):
从头到尾对数据进行两两比较进行交换,小的放前大的放后。这样一次下来,最大的元素就会被交换的最后,然后下一次循环就不用对最后一个元素进行比较交换了,所以呢每一次比较交换的次数都比上一次循环的次数少一,这样N次之后数据就变得升序排列了
unsigned long __stdcall BubbleSort(void* theArray)
3.2 选择排序思想:
{
long* Array = ((MySafeArray*)theArray)->data;
int iLength = ((MySafeArray*)theArray)->iLength;
int i, j=0;
long swap;
for (i = iLength-1; i > 0; i--)
{
for(j = 0; j < i; j++)
{
if(Array[j] > Array[j+1]) //前比后大,交换
{
swap = Array[j];
Array[j] = Array[j+1];
Array[j+1] = swap;
}
}
}
PrintResult(Array, iLength, "Bubble Sort"); //向控制台打印排序结果
InterlockedIncrement(&ThreadCompleted); //返回前使线程完成数标记加1
if(ThreadCompleted == 4) SetEvent(evtTerminate);//检查是否其他线程都已执行完
//若都执行完则设置程序结束信号量
return 0;
}
每一次都从无序的数据中找出最小的元素,然后和前面已经有序的元素序列的后一个元素进行交换,这样整个源序列就会分成两部分,前面一部分是已经排好序的有序序列,后面一部分是无序的,用于选出最小的元素。 循环N次之后,前面的有序序列加长到跟源序列一样长,后面的无序部分长度变为0,排序就完成了。
unsigned long __stdcall SelectSort(void* theArray)
3.3 堆排序思想:
{
long* Array = ((MySafeArray*)theArray)->data;
int iLength = ((MySafeArray*)theArray)->iLength;
long lMin, lSwap;
int i, j, iMinPos;
for(i=0; i < iLength-1; i++)
{
lMin = Array[i];
iMinPos = i;
for(j=i + 1; j <= iLength-1; j++) //从无序的元素中找出最小的元素
{
if(Array[j] < lMin)
{
iMinPos = j;
lMin = Array[j];
}
}
//把选出的元素交换拼接到有序序列的最后
lSwap = Array[i];
Array[i] = Array[iMinPos];
Array[iMinPos] = lSwap;
}
PrintResult(Array, iLength, "Select Sort"); //向控制台打印排序结果
InterlockedIncrement(&ThreadCompleted); //返回前使线程完成数标记加1
if(ThreadCompleted == 4) SetEvent(evtTerminate); //检查是否其他线程都已执行完
//若都执行完则设置程序结束信号量
return 0;
}
更多精彩
赞助商链接