SlideShare a Scribd company logo
Go Concurrency
                     March 27, 2013



                      John Graham-Cumming




www.cloudflare.com!
Fundamentals
 •  goroutines
    •  Very lightweight processes
    •  All scheduling handled internally by the Go runtime
    •  Unless you are CPU bound you do not have to think about
       scheduling
       
 •  Channel-based communication
    •  The right way for goroutines to talk to each other
       
 •  Synchronization Primitives
    •  For when a channel is too heavyweight
    •  Not covered in this talk




www.cloudflare.com!
goroutines
 •  “Lightweight”
     •  Starting 10,000 goroutines on my MacBook Pro took 22ms
     •  Allocated memory increased by 3,014,000 bytes (301 bytes per
        goroutine)
     •  https://gist.github.com/jgrahamc/5253020


 •  Not unusual at CloudFlare to have a single Go program
    running 10,000s of goroutines with 1,000,000s of
    goroutines created during life program.
    
 •  So, go yourFunc() as much as you like.




www.cloudflare.com!
Channels
 •  Quick syntax review

   c := make(chan bool)– Makes an unbuffered
   channel of bools

   c <- x – Sends a value on the channel

   <- c – Waits to receive a value on the channel

   x = <- c – Waits to receive a value and stores it in x

   x, ok = <- c – Waits to receive a value; ok will be
   false if channel is closed and empty.


www.cloudflare.com!
Unbuffered channels are best
 •  They provide both communication and synchronization
    func from(connection chan int) {!
        connection <- rand.Intn(100)!
    }!
    !
    func to(connection chan int) {!
        i := <- connection!
        fmt.Printf("Someone sent me %dn", i)!
    }!
    !
    func main() {!
        cpus := runtime.NumCPU()!
        runtime.GOMAXPROCS(cpus)!
    !
        connection := make(chan int)!
        go from(connection)!
        go to(connection)!
    }!

www.cloudflare.com!
Using channels for signaling
(1)
 •  Sometimes just closing a channel is enough

   c := make(chan bool)!
   !
   go func() {!
         !// ... do some stuff!
         !close(c)!
   }()!
   !
   // ... do some other stuff!
   <- c!




www.cloudflare.com!
Using channels for signaling (2) 
 •  Close a channel to coordinate multiple goroutines

   func worker(start chan bool) {!
       <- start!
       // ... do stuff!
   }!
   !
   func main() {!
       start := make(chan bool)!
   !
       for i := 0; i < 100; i++ {!
           go worker(start)!
       }!
   !
       close(start)!
   !
       // ... all workers running now!
   }!

www.cloudflare.com!
Select
 •  Select statement enables sending/receiving on multiple
   channels at once
        select {!
        case x := <- somechan:!
            // ... do stuff with x!
        !
        case y, ok := <- someOtherchan:!
            // ... do stuff with y!
            // check ok to see if someOtherChan!
            // is closed!
        !
        case outputChan <- z:!
            // ... ok z was sent!
        !
        default:!
            // ... no one wants to communicate!
        }!

www.cloudflare.com!
Common idiom: for/select!
        for {!
            select {!
            case x := <- somechan:!
                // ... do stuff with x!
        !
            case y, ok := <- someOtherchan:!
                // ... do stuff with y!
                // check ok to see if someOtherChan!
                // is closed!
        !
            case outputChan <- z:!
                // ... ok z was sent!
        !
            default:!
                // ... no one wants to communicate!
            }!
        }!


www.cloudflare.com!
Using channels for signaling (4)
 •  Close a channel to terminate multiple goroutines

   func worker(die chan bool) {!
       for {!
           select {!
               // ... do stuff cases!
           case <- die: !
               return!
           }!
       }!
   }!
   !
   func main() {!
       die := make(chan bool)!
       for i := 0; i < 100; i++ {!
           go worker(die)!
       }!
       close(die)!
   }!
www.cloudflare.com!
Using channels for signaling (5)
 •  Terminate a goroutine and verify termination

   func worker(die chan bool) {!
       for {!
           select {!
               // ... do stuff cases!
           case <- die:!
               // ... do termination tasks !
               die <- true!
               return!
           }!
       }!
   }!
   func main() {!
       die := make(chan bool)!
       go worker(die)!
       die <- true!
       <- die!
   }!
www.cloudflare.com!
Example: unique ID service
 •  Just receive from id to get a unique ID
 •  Safe to share id channel across routines
   id := make(chan string)!
   !
   go func() {!
        var counter int64 = 0!
        for {!
            id <- fmt.Sprintf("%x", counter)!
            counter += 1!
        }!
   }()!
   !
   x := <- id // x will be 1!
   x = <- id // x will be 2!




www.cloudflare.com!
Example: memory recycler
 func recycler(give, get chan []byte) {!
     q := new(list.List)!
 !
     for {!
         if q.Len() == 0 {!
             q.PushFront(make([]byte, 100))!
         }!
 !
         e := q.Front()!
 !
         select {!
         case s := <-give:!
             q.PushFront(s[:0])!
 !
         case get <- e.Value.([]byte):!
             q.Remove(e)!
         }!
     }!
 }!
www.cloudflare.com!
Timeout
 func worker(start chan bool) {!
     for {!
       !timeout := time.After(30 * time.Second)!
       !select {!
             // ... do some stuff!
 !
         case <- timeout:!
             return!
         }!
     }!        func worker(start chan bool) {!
                   timeout := time.After(30 * time.Second)!
 }!
                   for {!
                     !select {!
                           // ... do some stuff!
               !
                       case <- timeout:!
                           return!
                       }!
                   }!
               }!
www.cloudflare.com!
Heartbeat
 func worker(start chan bool) {!
     heartbeat := time.Tick(30 * time.Second)!
     for {!
       !select {!
             // ... do some stuff!
 !
         case <- heartbeat:!
             // ... do heartbeat stuff!
         }!
     }!
 }!




www.cloudflare.com!
Example: network multiplexor
 •  Multiple goroutines can send on the same channel

func worker(messages chan string) {!
    for {!
        var msg string // ... generate a message!
        messages <- msg!
    }!
}!
func main() {!
    messages := make(chan string)!
    conn, _ := net.Dial("tcp", "example.com")!
!
    for i := 0; i < 100; i++ {!
        go worker(messages)!
    }!
    for {!
        msg := <- messages!
        conn.Write([]byte(msg))!
    }!
}!
www.cloudflare.com!
Example: first of N
 •  Dispatch requests and get back the first one to complete
type response struct {!
    resp *http.Response!
    url string!
}!
!
func get(url string, r chan response ) {!
    if resp, err := http.Get(url); err == nil {!
        r <- response{resp, url}!
    }!
}!
!
func main() {!
    first := make(chan response)!
    for _, url := range []string{"http://code.jquery.com/jquery-1.9.1.min.js",!
        "http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js",!
        "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",!
        "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"} {!
        go get(url, first)!
    }!
!
    r := <- first!
    // ... do something!
}!
www.cloudflare.com!
range!
 •  Can be used to consume all values from a channel
func generator(strings chan string) {!
    strings <- "Five hour's New York jet lag"!
    strings <- "and Cayce Pollard wakes in Camden Town"!
    strings <- "to the dire and ever-decreasing circles"!
    strings <- "of disrupted circadian rhythm."!
    close(strings)!
}!
!
func main() {!
    strings := make(chan string)!
    go generator(strings)!
!
    for s := range strings {!
        fmt.Printf("%s ", s)!
    }!
    fmt.Printf("n");!
}!

www.cloudflare.com!
Passing a ‘response’ channel
 type work struct {!
     url string!
     resp chan *http.Response!
 }!
 !
 func getter(w chan work) {!
     for {!
         do := <- w!
         resp, _ := http.Get(do.url)!
         do.resp <- resp!
     }!
 }!
 !
 func main() {!
     w := make(chan work)!
 !
     go getter(w)!
 !
     resp := make(chan *http.Response)!
     w <- work{"http://cdnjs.cloudflare.com/jquery/1.9.1/jquery.min.js",!
         resp}!
 !
     r := <- resp!
 }!


www.cloudflare.com!
Buffered channels
 •  Can be useful to create queues
 •  But make reasoning about concurrency more difficult

   c := make(chan bool, 100) !




www.cloudflare.com!
Example: an HTTP load balancer
 •  Limited number of HTTP clients can make requests for
    URLs
 •  Unlimited number of goroutines need to request URLs
    and get responses
    
 •  Solution: an HTTP request load balancer




www.cloudflare.com!
A URL getter
 type job struct {!
     url string!
     resp chan *http.Response!
 }!
 !
 type worker struct {!
     jobs chan *job!
     count int!
 }!
 !
 func (w *worker) getter(done chan *worker) {!
     for {!
         j := <- w.jobs!
         resp, _ := http.Get(j.url)!
         j.resp <- resp!
         done <- w!
     }!
 }!

www.cloudflare.com!
A way to get URLs
 func get(jobs chan *job, url string, answer chan string) {!
         resp := make(chan *http.Response)!
         jobs <- &job{url, resp}!
         r := <- resp!
         answer <- r.Request.URL.String()!
 }!
 !
 func main() {!
         jobs := balancer(10, 10)!
         answer := make(chan string)!
         for {!
                 var url string!
                 if _, err := fmt.Scanln(&url); err != nil {!
                     break!
                 }!
                 go get(jobs, url, answer)!
         }!
         for u := range answer {!
                 fmt.Printf("%sn", u)!
         }!
 }!
www.cloudflare.com!
A load balancer
func balancer(count int, depth int) chan *job {!
    jobs := make(chan *job)!
    done := make(chan *worker)!
    workers := make([]*worker, count)!
!
    for i := 0; i < count; i++ {!
        workers[i] = &worker{make(chan *job,

            depth), 0}!
        go workers[i].getter(done)!
    }!
!                                          !
    go func() {!                                       select {!
        for {!                                         case j := <- jobsource:!
            var free *worker!                               free.jobs <- j!
            min := depth!                                   free.count++!
            for _, w := range workers {!   !
                 if w.count < min {!                   case w := <- done:!
                     free = w!                              w.count—!
                     min = w.count!                    }!
                 }!                                 }!
            }!                                 }()!
!                                          !
            var jobsource chan *job!           return jobs!
            if free != nil {!              }!
                 jobsource = jobs!
            }!
www.cloudflare.com!
Top 500 web sites loaded




www.cloudflare.com!
THANKS
    The Go Way: “small sequential pieces joined
    by channels”




www.cloudflare.com!

More Related Content

What's hot

Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golang
Basil N G
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
Sergey Pichkurov
 
Why you should care about Go (Golang)
Why you should care about Go (Golang)Why you should care about Go (Golang)
Why you should care about Go (Golang)
Aaron Schlesinger
 
GoLang Introduction
GoLang IntroductionGoLang Introduction
GoLang Introduction
Spandana Govindgari
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
Slawomir Dorzak
 
Go lang
Go langGo lang
Golang
GolangGolang
Golang
Felipe Mamud
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
Ishin Vin
 
Memory in go
Memory in goMemory in go
Memory in go
Iman Tunggono
 
Rust-lang
Rust-langRust-lang
Golang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewGolang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / Overview
Markus Schneider
 
The Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventureThe Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventure
mylittleadventure
 
Rust system programming language
Rust system programming languageRust system programming language
Rust system programming language
robin_sy
 
Golang getting started
Golang getting startedGolang getting started
Golang getting started
Harshad Patil
 
Go Programming Language by Google
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by Google
Uttam Gandhi
 
gRPC Design and Implementation
gRPC Design and ImplementationgRPC Design and Implementation
gRPC Design and Implementation
Varun Talwar
 
All you need to know about the JavaScript event loop
All you need to know about the JavaScript event loopAll you need to know about the JavaScript event loop
All you need to know about the JavaScript event loop
Saša Tatar
 
Rust Programming Language
Rust Programming LanguageRust Programming Language
Rust Programming Language
Jaeju Kim
 
Introduction to gRPC
Introduction to gRPCIntroduction to gRPC
Introduction to gRPC
Chandresh Pancholi
 
Deep drive into rust programming language
Deep drive into rust programming languageDeep drive into rust programming language
Deep drive into rust programming language
Vigneshwer Dhinakaran
 

What's hot (20)

Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golang
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
 
Why you should care about Go (Golang)
Why you should care about Go (Golang)Why you should care about Go (Golang)
Why you should care about Go (Golang)
 
GoLang Introduction
GoLang IntroductionGoLang Introduction
GoLang Introduction
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
 
Go lang
Go langGo lang
Go lang
 
Golang
GolangGolang
Golang
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
 
Memory in go
Memory in goMemory in go
Memory in go
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Golang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewGolang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / Overview
 
The Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventureThe Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventure
 
Rust system programming language
Rust system programming languageRust system programming language
Rust system programming language
 
Golang getting started
Golang getting startedGolang getting started
Golang getting started
 
Go Programming Language by Google
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by Google
 
gRPC Design and Implementation
gRPC Design and ImplementationgRPC Design and Implementation
gRPC Design and Implementation
 
All you need to know about the JavaScript event loop
All you need to know about the JavaScript event loopAll you need to know about the JavaScript event loop
All you need to know about the JavaScript event loop
 
Rust Programming Language
Rust Programming LanguageRust Programming Language
Rust Programming Language
 
Introduction to gRPC
Introduction to gRPCIntroduction to gRPC
Introduction to gRPC
 
Deep drive into rust programming language
Deep drive into rust programming languageDeep drive into rust programming language
Deep drive into rust programming language
 

Viewers also liked

Go Containers
Go ContainersGo Containers
Go Containers
jgrahamc
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
matthewrdale
 
Introduction to Go scheduler
Introduction to Go schedulerIntroduction to Go scheduler
Introduction to Go scheduler
Bin Wang
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
borderj
 
Concurrency patterns
Concurrency patternsConcurrency patterns
Concurrency patterns
Aaron Schlesinger
 
An introduction to programming in Go
An introduction to programming in GoAn introduction to programming in Go
An introduction to programming in Go
David Robert Camargo de Campos
 
Concurrent programming1
Concurrent programming1Concurrent programming1
Concurrent programming1
Nick Brandaleone
 
The low level awesomeness of Go
The low level awesomeness of GoThe low level awesomeness of Go
The low level awesomeness of Go
Jean-Bernard Jansen
 
Golang
GolangGolang
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
Hakim El Hattab
 

Viewers also liked (10)

Go Containers
Go ContainersGo Containers
Go Containers
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
 
Introduction to Go scheduler
Introduction to Go schedulerIntroduction to Go scheduler
Introduction to Go scheduler
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
Concurrency patterns
Concurrency patternsConcurrency patterns
Concurrency patterns
 
An introduction to programming in Go
An introduction to programming in GoAn introduction to programming in Go
An introduction to programming in Go
 
Concurrent programming1
Concurrent programming1Concurrent programming1
Concurrent programming1
 
The low level awesomeness of Go
The low level awesomeness of GoThe low level awesomeness of Go
The low level awesomeness of Go
 
Golang
GolangGolang
Golang
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
 

Similar to Go Concurrency

Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
Cloudflare
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
Cloudflare
 
A Channel Compendium
A Channel CompendiumA Channel Compendium
A Channel Compendium
Cloudflare
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
Andrey Breslav
 
Go memory
Go memoryGo memory
Go memory
jgrahamc
 
Go Memory
Go MemoryGo Memory
Go Memory
Cloudflare
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
jgrahamc
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
Cloudflare
 
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej GrzesikJDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
PROIDEA
 
Go, the one language to learn in 2014
Go, the one language to learn in 2014Go, the one language to learn in 2014
Go, the one language to learn in 2014
Andrzej Grzesik
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level Metrics
Philip Tellis
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
ElifTech
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
Naoki AINOYA
 
Elegant concurrency
Elegant concurrencyElegant concurrency
Elegant concurrency
Mosky Liu
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
Bo-Yi Wu
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
Kazunobu Tasaka
 
Programming ppt files (final)
Programming ppt files (final)Programming ppt files (final)
Programming ppt files (final)
yap_raiza
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
Konrad Malawski
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
Frank Müller
 
Hadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm ArchitectureHadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm Architecture
P. Taylor Goetz
 

Similar to Go Concurrency (20)

Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
 
A Channel Compendium
A Channel CompendiumA Channel Compendium
A Channel Compendium
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
Go memory
Go memoryGo memory
Go memory
 
Go Memory
Go MemoryGo Memory
Go Memory
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
 
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej GrzesikJDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
 
Go, the one language to learn in 2014
Go, the one language to learn in 2014Go, the one language to learn in 2014
Go, the one language to learn in 2014
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level Metrics
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
 
Elegant concurrency
Elegant concurrencyElegant concurrency
Elegant concurrency
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
 
Programming ppt files (final)
Programming ppt files (final)Programming ppt files (final)
Programming ppt files (final)
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Hadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm ArchitectureHadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm Architecture
 

More from jgrahamc

Better living through microcontrollers
Better living through microcontrollersBetter living through microcontrollers
Better living through microcontrollers
jgrahamc
 
Big O London Meetup April 2015
Big O London Meetup April 2015Big O London Meetup April 2015
Big O London Meetup April 2015
jgrahamc
 
How to launch and defend against a DDoS
How to launch and defend against a DDoSHow to launch and defend against a DDoS
How to launch and defend against a DDoS
jgrahamc
 
Lua: the world's most infuriating language
Lua: the world's most infuriating languageLua: the world's most infuriating language
Lua: the world's most infuriating language
jgrahamc
 
Software Debugging for High-altitude Balloons
Software Debugging for High-altitude BalloonsSoftware Debugging for High-altitude Balloons
Software Debugging for High-altitude Balloons
jgrahamc
 
That'll never work!
That'll never work!That'll never work!
That'll never work!
jgrahamc
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
jgrahamc
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Security
jgrahamc
 

More from jgrahamc (8)

Better living through microcontrollers
Better living through microcontrollersBetter living through microcontrollers
Better living through microcontrollers
 
Big O London Meetup April 2015
Big O London Meetup April 2015Big O London Meetup April 2015
Big O London Meetup April 2015
 
How to launch and defend against a DDoS
How to launch and defend against a DDoSHow to launch and defend against a DDoS
How to launch and defend against a DDoS
 
Lua: the world's most infuriating language
Lua: the world's most infuriating languageLua: the world's most infuriating language
Lua: the world's most infuriating language
 
Software Debugging for High-altitude Balloons
Software Debugging for High-altitude BalloonsSoftware Debugging for High-altitude Balloons
Software Debugging for High-altitude Balloons
 
That'll never work!
That'll never work!That'll never work!
That'll never work!
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Security
 

Recently uploaded

Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
Techgropse Pvt.Ltd.
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 

Recently uploaded (20)

Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 

Go Concurrency

  • 1. Go Concurrency March 27, 2013 John Graham-Cumming www.cloudflare.com!
  • 2. Fundamentals •  goroutines •  Very lightweight processes •  All scheduling handled internally by the Go runtime •  Unless you are CPU bound you do not have to think about scheduling •  Channel-based communication •  The right way for goroutines to talk to each other •  Synchronization Primitives •  For when a channel is too heavyweight •  Not covered in this talk www.cloudflare.com!
  • 3. goroutines •  “Lightweight” •  Starting 10,000 goroutines on my MacBook Pro took 22ms •  Allocated memory increased by 3,014,000 bytes (301 bytes per goroutine) •  https://gist.github.com/jgrahamc/5253020 •  Not unusual at CloudFlare to have a single Go program running 10,000s of goroutines with 1,000,000s of goroutines created during life program. •  So, go yourFunc() as much as you like. www.cloudflare.com!
  • 4. Channels •  Quick syntax review c := make(chan bool)– Makes an unbuffered channel of bools c <- x – Sends a value on the channel <- c – Waits to receive a value on the channel x = <- c – Waits to receive a value and stores it in x x, ok = <- c – Waits to receive a value; ok will be false if channel is closed and empty. www.cloudflare.com!
  • 5. Unbuffered channels are best •  They provide both communication and synchronization func from(connection chan int) {! connection <- rand.Intn(100)! }! ! func to(connection chan int) {! i := <- connection! fmt.Printf("Someone sent me %dn", i)! }! ! func main() {! cpus := runtime.NumCPU()! runtime.GOMAXPROCS(cpus)! ! connection := make(chan int)! go from(connection)! go to(connection)! }! www.cloudflare.com!
  • 6. Using channels for signaling (1) •  Sometimes just closing a channel is enough c := make(chan bool)! ! go func() {! !// ... do some stuff! !close(c)! }()! ! // ... do some other stuff! <- c! www.cloudflare.com!
  • 7. Using channels for signaling (2) •  Close a channel to coordinate multiple goroutines func worker(start chan bool) {! <- start! // ... do stuff! }! ! func main() {! start := make(chan bool)! ! for i := 0; i < 100; i++ {! go worker(start)! }! ! close(start)! ! // ... all workers running now! }! www.cloudflare.com!
  • 8. Select •  Select statement enables sending/receiving on multiple channels at once select {! case x := <- somechan:! // ... do stuff with x! ! case y, ok := <- someOtherchan:! // ... do stuff with y! // check ok to see if someOtherChan! // is closed! ! case outputChan <- z:! // ... ok z was sent! ! default:! // ... no one wants to communicate! }! www.cloudflare.com!
  • 9. Common idiom: for/select! for {! select {! case x := <- somechan:! // ... do stuff with x! ! case y, ok := <- someOtherchan:! // ... do stuff with y! // check ok to see if someOtherChan! // is closed! ! case outputChan <- z:! // ... ok z was sent! ! default:! // ... no one wants to communicate! }! }! www.cloudflare.com!
  • 10. Using channels for signaling (4) •  Close a channel to terminate multiple goroutines func worker(die chan bool) {! for {! select {! // ... do stuff cases! case <- die: ! return! }! }! }! ! func main() {! die := make(chan bool)! for i := 0; i < 100; i++ {! go worker(die)! }! close(die)! }! www.cloudflare.com!
  • 11. Using channels for signaling (5) •  Terminate a goroutine and verify termination func worker(die chan bool) {! for {! select {! // ... do stuff cases! case <- die:! // ... do termination tasks ! die <- true! return! }! }! }! func main() {! die := make(chan bool)! go worker(die)! die <- true! <- die! }! www.cloudflare.com!
  • 12. Example: unique ID service •  Just receive from id to get a unique ID •  Safe to share id channel across routines id := make(chan string)! ! go func() {! var counter int64 = 0! for {! id <- fmt.Sprintf("%x", counter)! counter += 1! }! }()! ! x := <- id // x will be 1! x = <- id // x will be 2! www.cloudflare.com!
  • 13. Example: memory recycler func recycler(give, get chan []byte) {! q := new(list.List)! ! for {! if q.Len() == 0 {! q.PushFront(make([]byte, 100))! }! ! e := q.Front()! ! select {! case s := <-give:! q.PushFront(s[:0])! ! case get <- e.Value.([]byte):! q.Remove(e)! }! }! }! www.cloudflare.com!
  • 14. Timeout func worker(start chan bool) {! for {! !timeout := time.After(30 * time.Second)! !select {! // ... do some stuff! ! case <- timeout:! return! }! }! func worker(start chan bool) {! timeout := time.After(30 * time.Second)! }! for {! !select {! // ... do some stuff! ! case <- timeout:! return! }! }! }! www.cloudflare.com!
  • 15. Heartbeat func worker(start chan bool) {! heartbeat := time.Tick(30 * time.Second)! for {! !select {! // ... do some stuff! ! case <- heartbeat:! // ... do heartbeat stuff! }! }! }! www.cloudflare.com!
  • 16. Example: network multiplexor •  Multiple goroutines can send on the same channel func worker(messages chan string) {! for {! var msg string // ... generate a message! messages <- msg! }! }! func main() {! messages := make(chan string)! conn, _ := net.Dial("tcp", "example.com")! ! for i := 0; i < 100; i++ {! go worker(messages)! }! for {! msg := <- messages! conn.Write([]byte(msg))! }! }! www.cloudflare.com!
  • 17. Example: first of N •  Dispatch requests and get back the first one to complete type response struct {! resp *http.Response! url string! }! ! func get(url string, r chan response ) {! if resp, err := http.Get(url); err == nil {! r <- response{resp, url}! }! }! ! func main() {! first := make(chan response)! for _, url := range []string{"http://code.jquery.com/jquery-1.9.1.min.js",! "http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js",! "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",! "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"} {! go get(url, first)! }! ! r := <- first! // ... do something! }! www.cloudflare.com!
  • 18. range! •  Can be used to consume all values from a channel func generator(strings chan string) {! strings <- "Five hour's New York jet lag"! strings <- "and Cayce Pollard wakes in Camden Town"! strings <- "to the dire and ever-decreasing circles"! strings <- "of disrupted circadian rhythm."! close(strings)! }! ! func main() {! strings := make(chan string)! go generator(strings)! ! for s := range strings {! fmt.Printf("%s ", s)! }! fmt.Printf("n");! }! www.cloudflare.com!
  • 19. Passing a ‘response’ channel type work struct {! url string! resp chan *http.Response! }! ! func getter(w chan work) {! for {! do := <- w! resp, _ := http.Get(do.url)! do.resp <- resp! }! }! ! func main() {! w := make(chan work)! ! go getter(w)! ! resp := make(chan *http.Response)! w <- work{"http://cdnjs.cloudflare.com/jquery/1.9.1/jquery.min.js",! resp}! ! r := <- resp! }! www.cloudflare.com!
  • 20. Buffered channels •  Can be useful to create queues •  But make reasoning about concurrency more difficult c := make(chan bool, 100) ! www.cloudflare.com!
  • 21. Example: an HTTP load balancer •  Limited number of HTTP clients can make requests for URLs •  Unlimited number of goroutines need to request URLs and get responses •  Solution: an HTTP request load balancer www.cloudflare.com!
  • 22. A URL getter type job struct {! url string! resp chan *http.Response! }! ! type worker struct {! jobs chan *job! count int! }! ! func (w *worker) getter(done chan *worker) {! for {! j := <- w.jobs! resp, _ := http.Get(j.url)! j.resp <- resp! done <- w! }! }! www.cloudflare.com!
  • 23. A way to get URLs func get(jobs chan *job, url string, answer chan string) {! resp := make(chan *http.Response)! jobs <- &job{url, resp}! r := <- resp! answer <- r.Request.URL.String()! }! ! func main() {! jobs := balancer(10, 10)! answer := make(chan string)! for {! var url string! if _, err := fmt.Scanln(&url); err != nil {! break! }! go get(jobs, url, answer)! }! for u := range answer {! fmt.Printf("%sn", u)! }! }! www.cloudflare.com!
  • 24. A load balancer func balancer(count int, depth int) chan *job {! jobs := make(chan *job)! done := make(chan *worker)! workers := make([]*worker, count)! ! for i := 0; i < count; i++ {! workers[i] = &worker{make(chan *job,
 depth), 0}! go workers[i].getter(done)! }! ! ! go func() {! select {! for {! case j := <- jobsource:! var free *worker! free.jobs <- j! min := depth! free.count++! for _, w := range workers {! ! if w.count < min {! case w := <- done:! free = w! w.count—! min = w.count! }! }! }! }! }()! ! ! var jobsource chan *job! return jobs! if free != nil {! }! jobsource = jobs! }! www.cloudflare.com!
  • 25. Top 500 web sites loaded www.cloudflare.com!
  • 26. THANKS The Go Way: “small sequential pieces joined by channels” www.cloudflare.com!