同时快速排序

时间:2017-06-24 18:31:19

标签: go concurrency goroutine

所以我在go中实现了一个快速排序算法。我用go test进行了测试,效果非常好。现在我想让它并发并检查计算时间的差异。算法如下所示:

package mysort

import (
    "math/rand"
)

// ConcurrentPartition - ConcurrentQuicksort function for partitioning the array (randomized choice of a pivot)
func ConcurrentPartition(A []int, p int, r int) int {
    index := rand.Intn(r-p) + p
    pivot := A[index]
    A[index] = A[r]
    A[r] = pivot
    x := A[r]
    j := p - 1
    i := p
    for i < r {
        if A[i] <= x {
            j++
            tmp := A[j]
            A[j] = A[i]
            A[i] = tmp
        }
        i++
    }
    temp := A[j+1]
    A[j+1] = A[r]
    A[r] = temp
    return j + 1
}

// ConcurrentQuicksort - a concurrent version of a quicksort algorithm
func ConcurrentQuicksort(A []int, p int, r int) {
    if p < r {
        q := ConcurrentPartition(A, p, r)
        ConcurrentQuicksort(A, p, q-1)
        ConcurrentQuicksort(A, q+1, r)
    }
}

默认情况下,每个ConcurrentQuicksort都是独立的divide and conquer哲学。所以我唯一做的就是在每次递归调用之前添加go关键字,如下所示:

go ConcurrentQuicksort(A, p, q-1)
go ConcurrentQuicksort(A, q+1, r)

我没有工作。正如我所见,它只是采用了一个数组,甚至没有一次调用递归快速排序。所以我添加了time导入和这一行:

time.Sleep(time.Second * 2)(那是在if之后)

它有效。所以我想它需要时间来完成所有操作。我现在怎么能不等待呢?我应该使用频道,还是以不同方式调用这些功能?

@Edit添加了这个:

func ConcurrentQuicksort(A []int, p int, r int, wg *sync.WaitGroup) {
    if p < r {
        q := ConcurrentPartition(A, p, r)
        wg.Add(2)
        go ConcurrentQuicksort(A, p, q-1, wg)
        go ConcurrentQuicksort(A, q+1, r, wg)
    }
}

1 个答案:

答案 0 :(得分:0)

您可以在此处使用public static void InCritical(this Mutex m, Action action) { m.WaitOne(); try { action(); } finally { m.ReleaseMutext() } } 包。创建WaitGroup实际上不会进一步深入到线程,直到所有的例程都完成了。它有非常简单的界面。以下是使用示例。

Mutex mutex = new Mutex(false, "SomeMutex");
while (true)
{
    if (CheckIfCanDoSomething())
    {
        mutex.InCritical(()=>
        {
            if (CheckIfCanDoSomething())
            {
                DoSomething();
            }
        });
        //at this point just recheck in while(true)
    }
    else
    {
        DoSomethingElse();
    }
}