简体   繁体   English

这是线程的问题吗? 如果是这样,我该如何解决?

[英]Is this an issue with threading? If so, how do I fix it?

I'm working on a project that involves 2 separate sorting algorithms running simultaneously.我正在开展一个项目,该项目涉及同时运行的 2 个单独的排序算法。 However, when the sorting finishes neither arrays are sorted, even if I run the same algorithm simultaneously.但是,当排序完成时,即使我同时运行相同的算法,也不会对两个数组进行排序。 I think it may be an error occurring within threading where one algorithm is taking the calculated answer from the other (but I'm not 100% sure).我认为这可能是线程中发生的错误,其中一个算法从另一个算法中获取计算出的答案(但我不是 100% 确定)。

It does work when only one algorithm is run.当只运行一种算法时它确实有效。

If this is the problem, do you know how to fix it?如果这是问题,您知道如何解决吗?

If that isn't the issue, then what is and how do I overcome it?如果这不是问题,那么问题是什么,我该如何克服?

Here's the code where the error occurs (the algorithms are held within their own classes):这是发生错误的代码(算法保存在它们自己的类中):

        string algorithmLeft = "";
        string algorithmRight = "";

        if (cboxDropDownLeft.SelectedItem != null)
        {
            algorithmLeft = cboxDropDownLeft.SelectedItem.ToString();
        }
        if (cboxDropDownRight.SelectedItem != null)
        {
            algorithmRight = cboxDropDownRight.SelectedItem.ToString();
        }

        ThreadStart tsLeft = delegate ()
        {
            try
            {
                switch (algorithmLeft)
                {
                    case ("Bubble Sort"):
                        Bubble_Sort bubbleSort = new Bubble_Sort();
                        bubbleSort.sortArray();
                        break;

                    case ("Merge Sort"):
                        Merge_Sort mergeSort = new Merge_Sort();
                        mergeSort.sortArray();
                        break;

                    case ("Quick Sort"):
                        Quick_Sort quickSort = new Quick_Sort();
                        quickSort.sortArray();
                        break;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

        };

        ThreadStart tsRight = delegate ()
        {
            try
            {
                switch (algorithmRight)
                {
                    case ("Bubble Sort"):
                        Bubble_Sort bubbleSort = new Bubble_Sort();
                        bubbleSort.sortArray();
                        break;

                    case ("Merge Sort"):
                        Merge_Sort mergeSort = new Merge_Sort();
                        mergeSort.sortArray();
                        break;

                    case ("Quick Sort"):
                        Quick_Sort quickSort = new Quick_Sort();
                        quickSort.sortArray();
                        break;

                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

        };

        if (algorithmLeft != "")
        {
            Thread tLeft = new Thread(tsLeft);
            tLeft.Start();
        }
        if (algorithmRight != "")
        {
            Thread tRight = new Thread(tsRight);
            tRight.Start();
        }

Bubble Sort:冒泡排序:

    public override void sortArray()
    {
        try
        {
            int n = arrayToSort.Count - 1;

            for (int loop1 = 0; loop1 < n; loop1++)
            {

                for (int loop2 = n; loop2 > loop1; loop2--)
                {
                    if (((IComparable)arrayToSort[loop2 - 1]).CompareTo(arrayToSort[loop2]) > 0)
                    {
                        object temp = arrayToSort[loop2];
                        arrayToSort[loop2] = arrayToSort[loop2 - 1];
                        arrayToSort[loop2 - 1] = temp;
                    }
                    Thread.Sleep(speed);
                }

            }
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

Merge Sort:合并排序:

    public override void sortArray()
    {
        try
        {
            sort(arrayToSort, 0, arrayToSort.Count - 1);
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }

    }

        public void sort(ArrayList arrayToSort, int left, int right)
    {
        if (left < right)
        {
            int m = left + (right - left) / 2;

            sort(arrayToSort, left, m);
            sort(arrayToSort, m + 1, right);
            merge(arrayToSort, left, m, right);
        }
    }

    public void merge(ArrayList data, int left, int mid, int right)
    {
        int i, j, k;
        int n1 = mid - left + 1;
        int n2 = right - mid;
        ArrayList L = new ArrayList(n1);
        ArrayList R = new ArrayList(n2);

        for (i = 0; i < n1; i++)
        {
            L.Add(data[left + i]);
        }

        for (j = 0; j < n2; j++)
        {
            R.Add(data[mid + 1 + j]);
        }

        i = 0;
        j = 0;
        k = left;

        while (i < n1 && j < n2)
        {
            if (((IComparable)L[i]).CompareTo(R[j]) < 0)
            {
                data[k] = L[i];
                i++;
            }
            else
            {
                data[k] = R[j];
                j++;
            }
            k++;
        }

        while (i < n1)
        {
            data[k] = L[i];
            i++;
            k++;
            Thread.Sleep(speed);
        }

        while (j < n2)
        {
            data[k] = R[j];
            j++;
            k++;
            Thread.Sleep(speed);
        }
    }

Quick Sort:快速排序:

    public int partition(ArrayList arrayToSort, int left, int right)
    {
        int pivot = (int)arrayToSort[left];

        while (true)
        {
            while (((IComparable)arrayToSort[left]).CompareTo(pivot) < 0)
            {
                left++;
            }

            while (((IComparable)arrayToSort[right]).CompareTo(pivot) > 0)
            {
                right--;
            }

            if (left < right)
            {
                object temp =arrayToSort[right];
                arrayToSort[right] = arrayToSort[left];
                arrayToSort[left] = temp;
                Thread.Sleep(speed);
            }
            else
            {
                return right;
            }
        }
    }

    public override void sortArray()
    {
        try
        {
            sort(arrayToSort, 0, arrayToSort.Count - 1);
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

    public void sort(ArrayList arr, int left, int right)
    {
        if (left < right)
        {
            int pivot = partition(arr, left, right);

            if (pivot > 1)
            {
                sort(arr, left, pivot - 1);
            }

            if (pivot + 1 < right)
            {
                sort(arr, pivot + 1, right);
            }
        }
    }

Algorithm for the creation of the 2 arrays that are to be sorted:创建要排序的 2 个数组的算法:

        ArrayCreator arrayCreator = new ArrayCreator();
        arrayCreator.createArray(arrayLeft);
        arrayRight = arrayLeft;

ArrayCreator:数组创建器:

    public void createArray(ArrayList array)
    {
        for (int i = 0; i < 50; i++)
        {
            Random rnd = new Random();
            int x = rnd.Next(1, 400);
            array.Add(x);
            Thread.Sleep(15);
        }
    }

You have stated that the sorting is working if a single thread is running one of the algorithms, but when you use different algorithms, then the result is no longer right.您已经声明,如果单个线程正在运行其中一种算法,则排序有效,但是当您使用不同的算法时,结果不再正确。 This means that the threads are preventing each-other from achieving success.这意味着线程正在阻止彼此取得成功。

Let me explain: Let's assume you have two threads, T1 and T2.让我解释一下:假设您有两个线程,T1 和 T2。 If both of them are comparing x and y then you have two possible scenarios如果他们都在比较 x 和 y 那么你有两种可能的情况

Scenario1场景1

T1 compares x and y and realizes they need to be swapped T1 swaps x and y T2 copmares x and y and realizes they are in correct order T1 比较 x 和 y 并意识到它们需要交换 T1 交换 x 和 y T2 比较 x 和 y 并意识到它们的顺序正确

Result: Success结果:成功

Scenario2场景2

T1 compares x and y and realizes they need to be swapped T2 compares x and y and realizes they need to be swapped T1 swaps x and y T2 swaps y and x T1 比较 x 和 y 并意识到它们需要交换 T2 比较 x 和 y 并意识到它们需要交换 T1 交换 x 和 y T2 交换 y 和 x

Result: Failure, T2 was making the comparison after T1 made the comparison, but before T1 made the swap.结果:失败,T2 在 T1 进行比较之后进行比较,但在 T1 进行交换之前。

As a result, this is unsafe.结果,这是不安全的。 It is much better to let the Threads sort their own partition of the problem space and then mergesort the sorted subsets.最好让线程对它们自己的问题空间分区进行排序,然后对排序后的子集进行归并排序。

Cloning arrayLeft solved the problem.克隆 arrayLeft 解决了这个问题。

Thanks for all the help, it was much appreciated.感谢所有帮助,非常感谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM