Приоритетная очередь в GoLang с использованием каналов - PullRequest
0 голосов
/ 18 ноября 2018

Вопрос

На изображении выше показан вопрос, решение которого мне необходимо решить.вот решение, которое я придумал (должно быть закодировано в Go).Я получаю ошибку взаимоблокировки:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /home/kypriank/Assignment 5/priorityqueue.go:42 +0x1a3

goroutine 17 [chan send]:
main.priorityQueue(0xc420080060, 0xc4200800c0)
    /home/kypriank/Assignment 5/priorityqueue.go:22 +0x1a2
created by main.main
    /home/kypriank/Assignment 5/priorityqueue.go:40 +0xe5
exit status 2

Интересно, может ли кто-нибудь помочь мне выяснить, где происходит сбой моего кода (основная функция имеет некоторый код для проверки моего решения):

package main

var numOrder [20] int
var mesOrder [] PriorityMessage
var pri int
var a int

type PriorityMessage struct {
    Priority int // between 0 and 9
    Message string
}

func priorityQueue(west chan PriorityMessage, east chan string) {
    incomming := <-west
    if numOrder[incomming.Priority] == 10 {
        numOrder[incomming.Priority] = incomming.Priority
    }else {numOrder[incomming.Priority+1] = incomming.Priority}
    mesOrder = append(mesOrder, incomming)
    for i := 0; i < len(numOrder); i++ {if numOrder[i] != 10 {pri = 
numOrder[i]; a = i; break}}
    for i := 0; i < len(mesOrder); i++ {
        if pri == mesOrder[i].Priority {
            east <- (mesOrder[i]).Message
            numOrder[a] = 10
            mesOrder = append(mesOrder[:i], mesOrder[i+1:]...) 
        }
    }
}

var west chan PriorityMessage
var east chan string

func printToScreen() {
    for {println(<- east)}
}

func main() {
    for i := 0; i < len(numOrder); i++ {numOrder[i] = 10}
    west = make(chan PriorityMessage)
    east = make(chan string)
    go priorityQueue(west, east)
    west <- PriorityMessage{1, "one"}
    west <- PriorityMessage{0, "zero"}
    west <- PriorityMessage{2, "two"}
    west <- PriorityMessage{1, "another one"}
    west <- PriorityMessage{0, "another zero"}
    go printToScreen()
    select {} // to allow all messages to be printed
}

1 Ответ

0 голосов
/ 19 ноября 2018

На самом деле я не смотрел на приоритетное поведение очереди, а сосредоточился на тупике.

Итак, у вас есть несколько проблем, которые могут завести вас в тупик:

  1. Вы читаете из west только один раз, однако пишете в него несколько раз.Это означает, что он заблокируется, когда вы напишите zero.Возможно, добавьте цикл for.
  2. go printToScreen() после всех операций записи в west.Это означает, что когда вы выполняете обычное чтение из west, а затем записываете в east, попадаете в записывающую часть, оно блокируется, потому что ничего не читает из east.
  3. Пустой выбор (select{}),В то время как это заблокирует основную процедуру запуска, это будет происходить бесконечно.Это вызовет тупиковую панику, как только закроются все остальные подпрограммы.

Я изменил ваш код следующим образом:

package main

import "time"

var numOrder [20]int
var mesOrder []PriorityMessage
var pri int
var a int

type PriorityMessage struct {
    Priority int // between 0 and 9
    Message  string
}

func priorityQueue(west chan PriorityMessage, east chan string) {
    for {
        incomming := <-west
        if numOrder[incomming.Priority] == 10 {
            numOrder[incomming.Priority] = incomming.Priority
        } else {
            numOrder[incomming.Priority+1] = incomming.Priority
        }
        mesOrder = append(mesOrder, incomming)
        for i := 0; i < len(numOrder); i++ {
            if numOrder[i] != 10 {
                pri =
                    numOrder[i]
                a = i
                break
            }
        }
        for i := 0; i < len(mesOrder); i++ {
            if pri == mesOrder[i].Priority {
                east <- (mesOrder[i]).Message
                numOrder[a] = 10
                mesOrder = append(mesOrder[:i], mesOrder[i+1:]...)
            }
        }
    }
}

var west chan PriorityMessage
var east chan string

func printToScreen() {
    for {
        println(<-east)
    }
}

func main() {
    for i := 0; i < len(numOrder); i++ {
        numOrder[i] = 10
    }
    go printToScreen()
    west = make(chan PriorityMessage)
    east = make(chan string)
    go priorityQueue(west, east)
    west <- PriorityMessage{1, "one"}
    west <- PriorityMessage{0, "zero"}
    west <- PriorityMessage{2, "two"}
    west <- PriorityMessage{1, "another one"}
    west <- PriorityMessage{0, "another zero"}

    time.Sleep(time.Hour)
}

И получим следующие результаты:

one
zero
two
another one
another zero
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...