如何解决死锁问题?

huangapple go评论85阅读模式
英文:

How can I fix the deadlock?

问题

程序必须在我写入第一个通道时打印num的平方根,如果写入第二个通道,则打印3*num,如果写入stop通道,则结束程序。我无法理解通道被阻塞的位置。

package main

import (
	"fmt"
)

func main() {
	ch1, ch2 := make(chan int), make(chan int)
	stop := make(chan struct{})

	r := calculator(ch1, ch2, stop)

	//ch1 <- 3
	ch2 <- 2
	//<-stop
	fmt.Println(<-r)

}

func calculator(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int {
	returnChan := make(chan int)
	go func() {
		defer close(returnChan)
		select {
		case <-firstChan:
			returnChan <- (<-firstChan) * (<-firstChan)
		case <-secondChan:
			returnChan <- (<-secondChan) * 3
		case <-stopChan:
			close(returnChan)
		}
	}()
	return returnChan
}
英文:

The programm must print sqrt of num if I write to first channel, 3*num if to secon, complete if to stop. I can't understand where is channel blocked.

package main

import (
&quot;fmt&quot;
)

func main() {
ch1, ch2 := make(chan int), make(chan int)
stop := make(chan struct{})

r := calculator(ch1, ch2, stop)

//ch1 &lt;- 3
ch2 &lt;- 2
//&lt;-stop
fmt.Println(&lt;-r)

}

func calculator(firstChan &lt;-chan int, secondChan &lt;-chan int, stopChan &lt;-chan struct{}) &lt;-chan int {
returnChan := make(chan int)
go func() {
	defer close(returnChan)
	select {
	case &lt;-firstChan:
		returnChan &lt;- (&lt;-firstChan) * (&lt;-firstChan)
	case &lt;-secondChan:
		returnChan &lt;- (&lt;-secondChan) * 3
	case &lt;-stopChan:
		close(returnChan)
	}
}()
return returnChan
}

答案1

得分: 1

你正在阅读的是 case 语句:

case <-firstChan

在 case 块内部是:

...(<-firstChan) * (<-firstChan)

当只有一个值发送到通道中时,你总共读取了三次。

在 case 语句中将值存储到一个变量中,并在块中使用它,如下所示:

func calculator(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int {
	returnChan := make(chan int)
	go func() {
		defer close(returnChan)
		select {
		case firstChanVal := <-firstChan:
			returnChan <- firstChanVal * firstChanVal
		case firstChanVal := <-secondChan:
			returnChan <- firstChanVal * 3
		case <-stopChan:
			close(returnChan)
		}
	}()
	return returnChan
}

Go play ground 演示

英文:

You are reading from the case statement:

case &lt;-firstChan

and within case block:

...(&lt;-firstChan) * (&lt;-firstChan)

all together you read three times when only one was sent into the channel.

Get the value to a var in the case statement and use it in the block like below:

func calculator(firstChan &lt;-chan int, secondChan &lt;-chan int, stopChan &lt;-chan struct{}) &lt;-chan int {
	returnChan := make(chan int)
	go func() {
		defer close(returnChan)
		select {
		case firstChanVal := &lt;-firstChan:
			returnChan &lt;- firstChanVal * firstChanVal
		case firstChanVal := &lt;-secondChan:
			returnChan &lt;- firstChanVal * 3
		case &lt;-stopChan:
			close(returnChan)
		}
	}()
	return returnChan
}

Go play ground demo

答案2

得分: 0

当你调用<-firstChan时,程序将暂停并等待一个值发送到firstChan,你调用了3次<-firstChan,但只发送了1次,程序将永远暂停。

英文:

When you call <-firstChan, the program will be paused and wait for a value to send to firstChan, you call 3 times <-firstChan while you only send 1 time, the program will pause forever

huangapple
  • 本文由 发表于 2023年2月12日 19:50:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75426765.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定