程序执行被卡住

时间:2018-11-24 16:06:07

标签: multithreading go

我正在尝试在多线程环境中运行以下工作线程,但似乎所有线程都卡住了,而且它们都无法继续运行。

func executeTask(currentTask task, serial bool, imagePixels map[string]*imagePixelContainer, completedTracker map[string]*partsCompleted,
    bufferPixels map[string]*imagePixelContainer, nextEffects map[string]*nextEffect, pl *sync.Mutex, threadid int) {

    newPixels := applyEffect(imagePixels[currentTask.image].pixels, currentTask.effect, currentTask.starty, currentTask.endy)
    mergeComputation(newPixels, bufferPixels[currentTask.image], currentTask.starty, currentTask.endy)
    completedTracker[currentTask.image].mux.Lock()
    completedTracker[currentTask.image].completed += 1
    if completedTracker[currentTask.image].completed == 3 {
        imagePixels[currentTask.image].mux.Lock()
        imagePixels[currentTask.image].pixels = duplicate(bufferPixels[currentTask.image].pixels)
        imagePixels[currentTask.image].mux.Unlock()
        completedTracker[currentTask.image].completed = 0
        nextEffects[currentTask.image].mux.Lock()
        nextEffects[currentTask.image].index += 1
        nextEffects[currentTask.image].mux.Unlock()
    }
    completedTracker[currentTask.image].mux.Unlock()
}

func mergeComputation(computedPixels [][]Pixel, storing *imagePixelContainer, starty int, endy int) {
    storing.mux.Lock()
    for y := 0; y < len(computedPixels); y++ {
        for x := 0; x < len(computedPixels[y]); x++ {
            storing.pixels[starty][x] = computedPixels[y][x]
        }
        starty += 1
    }
    storing.mux.Unlock()
}

// Worker threads that get spawned
func worker(que *Queue, nextEffects map[string]*nextEffect, effectorder map[string][]string, imagePixels map[string]*imagePixelContainer,
    completedTracker map[string]*partsCompleted, bufferPixels map[string]*imagePixelContainer, printlock *sync.Mutex, counter *int, threadid int) {
    for !(que.Empty()) {
        ctask := que.Pop()
        if ctask.effect != "" { // Indicates that the task queue is empty at this moment
            nextEffects[ctask.image].mux.Lock()
            cond := ctask.effect != effectorder[ctask.image][nextEffects[ctask.image].index]
            nextEffects[ctask.image].mux.Unlock()
            if cond {
                que.Push(ctask)
            } else {
                executeTask(ctask, false, imagePixels, completedTracker, bufferPixels, nextEffects, printlock, threadid)
            }
        }
    }
    *counter -= 1
}

队列的Push和Pop是线程安全的。每个映射对象都有一个指向指针结构的字符串键,该指针结构保存数据变量和一个互斥量变量以保护该数据。感谢您的帮助:)

0 个答案:

没有答案