Answer the question
In order to leave comments, you need to log in
Deadlock - how to close the channel correctly?
Hello! I am new to Go. The task is this: data is passed to the input, hashed and passed further to the MultiHash function, then MultiHash must read them again, hash them and pass them to the next function. An attempt to implement pipeline. An anonymous function in the main function tries to read the data and it succeeds, but after reading all the data, the program still falls into a deadlock. This article says that the program falls into a deadlock if we try to read data through range, if the channel is not closed. Am I right in thinking that I have the same error? I tried everything and an infinite loop and select and close the channel, if I close it in MultiHash, I have a panic. Could you explain what is my mistake and how to fix it?
signer.go
package main
import (
"fmt"
"os"
"strconv"
"sync"
)
// сюда писать код
func SingleHash(wg *sync.WaitGroup, done chan interface{}, in []string) {
defer close(done)
defer wg.Done()
fmt.Println(in)
wgsh := &sync.WaitGroup{}
mu := &sync.Mutex{}
for _, i := range in {
wgsh.Add(1)
go workerSingleHash(wgsh, mu, i, done)
}
wgsh.Wait()
fmt.Println("end singlehash")
}
func workerSingleHash(wg *sync.WaitGroup, mu *sync.Mutex, in string, done chan interface{}) {
defer wg.Done()
crc32Chan := make(chan string)
mu.Lock()
md5Data := DataSignerMd5(in)
mu.Unlock()
go asyncCrc32Signer(in, crc32Chan)
crc32Data := <-crc32Chan
crc32Md5Data := DataSignerCrc32(md5Data)
done <- crc32Data + "~" + crc32Md5Data
}
func asyncCrc32Signer(data string, out chan string) {
//defer close(out)
out <- DataSignerCrc32(data)
}
func MultiHash(wg *sync.WaitGroup, done chan interface{}, done2 chan string) chan string {
wgD := &sync.WaitGroup{}
defer wg.Done()
j := 0
for v := range done {
fmt.Println("v: ", v)
str := fmt.Sprintf("%v", v)
wgD.Add(1)
go asyncWorker(wgD, j, str, done2)
j++
}
wgD.Wait()
return done2
}
func asyncWorker(wgDone2 *sync.WaitGroup, increment int, in string, done2 chan string) {
wgDone2.Done()
j := strconv.Itoa(increment)
done2 <- DataSignerCrc32(j + in)
}
func main() {
wg := &sync.WaitGroup{}
wg.Add(2)
done := make(chan interface{})
done2 := make(chan string)
in := os.Args
go SingleHash(wg, done, in[1:])
result := MultiHash(wg, done, done2)
func(done2 chan string) {
for v := range done2 {
fmt.Println("combine result: ", v)
}
}(result)
wg.Wait()
fmt.Println("end")
}
package main
import (
"crypto/md5"
"fmt"
"hash/crc32"
"strconv"
"sync/atomic"
"time"
)
type job func(in, out chan interface{})
const (
MaxInputDataLen = 100
)
var (
dataSignerOverheat uint32 = 0
DataSignerSalt = ""
)
var OverheatLock = func() {
for {
if swapped := atomic.CompareAndSwapUint32(&dataSignerOverheat, 0, 1); !swapped {
fmt.Println("OverheatLock happend")
time.Sleep(time.Second)
} else {
break
}
}
}
var OverheatUnlock = func() {
for {
if swapped := atomic.CompareAndSwapUint32(&dataSignerOverheat, 1, 0); !swapped {
fmt.Println("OverheatUnlock happend")
time.Sleep(time.Second)
} else {
break
}
}
}
var DataSignerMd5 = func(data string) string {
OverheatLock()
defer OverheatUnlock()
data += DataSignerSalt
dataHash := fmt.Sprintf("%x", md5.Sum([]byte(data)))
time.Sleep(10 * time.Millisecond)
return dataHash
}
var DataSignerCrc32 = func(data string) string {
data += DataSignerSalt
crcH := crc32.ChecksumIEEE([]byte(data))
dataHash := strconv.FormatUint(uint64(crcH), 10)
time.Sleep(time.Second)
return dataHash
}
[3 4 5 6]
v: 4088798008~2157876746
v: 498629140~3068393833
v: 2226203566~3690458478
v: 1842515611~1684880638
end singlehash
combine result: 1341606222
combine result: 4202847257
combine result: 966776312
combine result: 1549563179
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main.func1(0xc000086120)
C:/Users/engis/OneDrive/Рабочий стол/Go-learn-master/Go-learn-master/hw2_signer/signer.go:91 +0xe5
main.main()
C:/Users/engis/OneDrive/Рабочий стол/Go-learn-master/Go-learn-master/hw2_signer/signer.go:94 +0x13b
exit status 2
Answer the question
In order to leave comments, you need to log in
My version: https://github.com/igorzakhar/pipeline_signer/blob...
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question