How can I break out of a goroutine if a condition is met?

435 views
Skip to first unread message

Tenjin

unread,
Jul 20, 2021, 12:29:22 PM7/20/21
to golang-nuts
I am wanting to try and login to mutiple servers at once (bruteforce) now I am spawning a new goroutine for each set of credentials. I want to be able to break out of my loop that I have once a successful login is met, as of right now the program just throws a panic and I am unsure of what I can do.

Brian Candler

unread,
Jul 20, 2021, 1:44:28 PM7/20/21
to golang-nuts
Which goroutine panics: the one which got a successful login, or the other ones?

If the goroutine which sees a successful login panics, then that's a problem with that particular goroutine, and you'll need to debug it in the normal way.  Reading the panic message carefully would be a good starting point.

Note that you don't "break out" of a goroutine; you can break out of a loop.  You can terminate a goroutine simply by returning from the function that was invoked by "go <somefunc>"

If you want to terminate the other goroutines, then the standard way to do that is to use a Context, and signal the context as "done".  If those goroutines are blocked on I/O, they should be modified so that they make use of the context too. There is a blog post here you'll find useful.  But it seems to me this is a separate problem to the one of the original goroutine throwing a panic.

Dimas Prawira

unread,
Jul 20, 2021, 3:21:27 PM7/20/21
to golang-nuts
I personally like to use range channel to "break out" process in goroutine, for example :

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    c := make(chan bool)
    wg.Add(1)
    go func() {
        defer wg.Done()
        for b := range c {
            fmt.Printf("Hello %t\n", b)
        }
    }()
    c <- true
    c <- true
    close(c)
    wg.Wait()
}
Dave Chenney has great post about this post : http://dave.cheney.net/2013/04/30/curious-channels.
Hope this helps



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f1953fe9-0cef-4f24-bf72-804a078bcb7an%40googlegroups.com.

Gergely Brautigam

unread,
Jul 21, 2021, 2:04:27 AM7/21/21
to golang-nuts
I think this is a perfect scenario for sync.Cond https://pkg.go.dev/sync#Cond.

Brian Candler

unread,
Jul 21, 2021, 4:05:10 AM7/21/21
to golang-nuts
Channels are almost always better than low-level primitives like condition variables, which have various pitfalls.

This video by Bryan C Mills explains some of the issues, and shows channel-based alternatives:

Gergely Brautigam

unread,
Jul 21, 2021, 4:37:13 AM7/21/21
to golang-nuts
On Wednesday, 21 July 2021 at 10:05:10 UTC+2 Brian Candler wrote:
Channels are almost always better than low-level primitives like condition variables, which have various pitfalls.

Almost always. :) Sure, there are alternatives, but sync.Cond makes sense once you use it properly. And it can be signalled multiple times. It's a really nice primitve, I think.
Reply all
Reply to author
Forward
0 new messages