You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
i have study golang for only 3 weeks i can not solve this problem
if someone can help me to find out the reason why my program will block;
i do many goroutine it has some wrong result ,some ip can ping right but pinger.PacketsRecv = 0
i tried to find the reason, and i got some message
var wg sync.WaitGroup
recv := make(chan *packet, 5)
defer close(recv)
wg.Add(1)
go p.recvICMP(conn, recv, &wg)
err := p.sendICMP(conn)
if err != nil {
fmt.Println(err.Error())
}
timeout := time.NewTicker(p.Timeout)
defer timeout.Stop()
interval := time.NewTicker(p.Interval)
defer interval.Stop()
for {
select {
case <-p.done:
wg.Wait()
return
case <-timeout.C:
close(p.done)
wg.Wait()
return
case <-interval.C:
if p.Count > 0 && p.PacketsSent >= p.Count {
continue
}
err = p.sendICMP(conn)
if err != nil {
fmt.Println("FATAL: ", err.Error())
}
case r := <-recv:
err := p.processPacket(r)
if err != nil {
fmt.Println("FATAL: ", err.Error())
}
}
if p.Count > 0 && p.PacketsRecv >= p.Count {
close(p.done)
wg.Wait()
return
}
}
i need to ping almost 16000 server ,if i use more goroutine to do this , block happen frequently
i debug my code , i found the reason
in ping.go 406
`
defer wg.Done()
for {
select {
case <-p.done:
fmt.Println("ok")
return
default:
bytes := make([]byte, 512)
conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
var n, ttl int
var err error
if p.ipv4 {
var cm *ipv4.ControlMessage
n, cm, _, err = conn.IPv4PacketConn().ReadFrom(bytes)
if cm != nil {
ttl = cm.TTL
}
} else {
var cm *ipv6.ControlMessage
n, cm, _, err = conn.IPv6PacketConn().ReadFrom(bytes)
if cm != nil {
ttl = cm.HopLimit
}
}
if err != nil {
if neterr, ok := err.(*net.OpError); ok {
if neterr.Timeout() {
// Read timeout
continue
} else {
close(p.done)
return
}
}
}
fmt.Println(len(recv))
recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}
}
}
`
the wg.Wait() is blocked by p.recvICMP(conn, recv, &wg)
and in the func recvICMP i foud in the for cycle recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}
it will block by send a msg to the channel recv
but the chan recv := make(chan *packet, 5) only 5 size
if i do more goroutine i found the size 5 is not enough, so it will be blocked because the full channel ,
ok in some coincidence time the main goroutine dose not do the comsume func case r := <-recv,
it is do close(p.done) then do wg.Wait() block to wait recvICMP
but in recvICMP case <-p.done: fmt.Println("ok") return
this code will not effective because the block send msg to channel recv,so will not do defer wg.Done()
then they all block like a deadlock
i sorry to my poor english
i don't konw i say my question clear
now i just do this to solve recv := make(chan *packet, 100)
by the way do many goroutine it has some wrong result ,some ip can ping right but pinger.PacketsRecv = 0
The text was updated successfully, but these errors were encountered:
i have study golang for only 3 weeks i can not solve this problem
pinger.PacketsRecv = 0
i tried to find the reason, and i got some message
i need to ping almost 16000 server ,if i use more goroutine to do this , block happen frequently
i debug my code , i found the reason
in ping.go 406
`
defer wg.Done()
for {
select {
case <-p.done:
fmt.Println("ok")
return
default:
bytes := make([]byte, 512)
conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
var n, ttl int
var err error
if p.ipv4 {
var cm *ipv4.ControlMessage
n, cm, _, err = conn.IPv4PacketConn().ReadFrom(bytes)
if cm != nil {
ttl = cm.TTL
}
} else {
var cm *ipv6.ControlMessage
n, cm, _, err = conn.IPv6PacketConn().ReadFrom(bytes)
if cm != nil {
ttl = cm.HopLimit
}
}
if err != nil {
if neterr, ok := err.(*net.OpError); ok {
if neterr.Timeout() {
// Read timeout
continue
} else {
close(p.done)
return
}
}
}
fmt.Println(len(recv))
recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}
}
}
`
the
wg.Wait()
is blocked byp.recvICMP(conn, recv, &wg)
and in the func recvICMP i foud in the for cycle
recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}
it will block by send a msg to the channel recv
but the chan
recv := make(chan *packet, 5)
only 5 sizeif i do more goroutine i found the size 5 is not enough, so it will be blocked because the full channel ,
ok in some coincidence time the main goroutine dose not do the comsume func
case r := <-recv
,it is do
close(p.done)
then dowg.Wait()
block to wait recvICMPbut in recvICMP
case <-p.done: fmt.Println("ok") return
this code will not effective because the block send msg to channel recv,so will not do
defer wg.Done()
then they all block like a deadlock
i sorry to my poor english
i don't konw i say my question clear
now i just do this to solve
recv := make(chan *packet, 100)
by the way do many goroutine it has some wrong result ,some ip can ping right but
pinger.PacketsRecv = 0
The text was updated successfully, but these errors were encountered: