使用多线程进行正确排序时遇到问题。 Bitonic排序在SingleThread中正常工作,但在MultiThread中返回的结果并不完全正确。有什么问题?我怀疑这可能是一些线程冲突(竞争条件)?
public class MultiThreadedSorter : BaseBitonicSorter
{
private int minimumLength = 1;
public override void Sort(ref int[] array)
{
a = array;
minimumLength = a.Length / Environment.ProcessorCount; // przydział procesów
BitonicSort(new BitonicParameters(0, a.Length, Ascending));
}
private void BitonicSort(object AsyncState)
{
BitonicParameters parameters = (BitonicParameters)AsyncState;
if (parameters.Length > 1)
{
if (parameters.Length > minimumLength)
{
int median = parameters.Length / 2;
Thread left = new Thread(BitonicSort);
Thread right = new Thread(BitonicSort);
left.Start(new BitonicParameters(parameters.Index, median, Ascending));
right.Start(new BitonicParameters(parameters.Index + median, median, Descending));
left.Join();
right.Join();
}
else
{
int median = (parameters.Length / 2);
if (median > 1)
{
BitonicSort(new BitonicParameters(parameters.Index, median, Ascending));
BitonicSort(new BitonicParameters(parameters.Index, median, Ascending));
}
}
BitonicMerge(new BitonicParameters(parameters.Index, parameters.Length, parameters.Direction));
}
}
private void BitonicMerge(object AsyncState)
{
BitonicParameters parameters = (BitonicParameters)AsyncState;
if (parameters.Length > 1)
{
if (parameters.Length > minimumLength)
{
int median = (parameters.Length / 2);
for (int i = parameters.Index; i < (parameters.Index + median); i++)
{
Compare(i, (i + median), parameters.Direction);
}
Thread left = new Thread(BitonicMerge);
Thread right = new Thread(BitonicMerge);
left.Start(new BitonicParameters(parameters.Index, median, parameters.Direction));
right.Start(new BitonicParameters(parameters.Index + median, median, parameters.Direction));
left.Join();
right.Join();
}
else
{
int median = (parameters.Length / 2);
for (int i = parameters.Index; i < (parameters.Index + median); i++)
{
Compare(i, (i + median), parameters.Direction);
}
if (median > 1)
{
BitonicMerge(new BitonicParameters(parameters.Index, median, parameters.Direction));
BitonicMerge(new BitonicParameters(parameters.Index + median, median, parameters.Direction));
}
}
}
}
private struct BitonicParameters
{
public BitonicParameters(int index, int length, bool direction)
{
Index = index;
Length = length;
Direction = direction;
}
public int Index;
public int Length;
public bool Direction;
}
}
public class SingleThreadedBitonicSorter : BaseBitonicSorter
{
public override void Sort(ref int[] array)
{
a = array;
BitonicSort(0, a.Length, Ascending);
}
private void BitonicSort(int index, int length, bool direction)
{
if (length > 1)
{
int median = (length / 2);
if (median > 1)
{
BitonicSort(index, median, Ascending);
BitonicSort(index + median, median, Descending);
}
BitonicMerge(index, length, direction);
}
}
private void BitonicMerge(int index, int length, bool direction)
{
if (length > 1)
{
int median = (length / 2);
for (int i = index; i < (index + median); i++)
{
Compare(i, (i + median), direction);
}
if (median > 1)
{
BitonicMerge(index, median, direction);
BitonicMerge((index + median), median, direction);
}
}
}
}