Upload
francisco-souza
View
302
Download
3
Embed Size (px)
DESCRIPTION
Palestra apresentada no DevCamp 2014, sobre concorrência e paralelismo em Go.
Citation preview
Concorrência e Paralelismo em Go
Francisco Souza @franciscosouza
what the f**rancisco?!
• Globo.com
• tsuru
• Go
Concorrência & Paralelismo
http://vimeo.com/49718712
Por que?
The free lunch is over
“Most classes of applications have enjoyed free and regular performance gains for several decades, even without releasing new versions or doing anything special...- Herb Sutter, 2005 ”
“Concurrency is not just for doing more things faster. It's for writing better code.
- Andrew Gerrand, 2014 ”
Threading
static long values_sum = 0; !int main(void) { thrd_t threads[NTHREADS]; long i; int status; for(i = 0; i < NTHREADS; i++) { thrd_create(&threads[i], sum, (void *)i); } for(i = 0; i < NTHREADS; i++) { thrd_join(threads[i], &status); } printf("%ld\n", values_sum); }
int sum(void *arg) { long id = (long)arg; int i, start, end; start = id * (N / NTHREADS + 1); end = start + (N / NTHREADS + 1); for(i = start; i < end; i++) { if(i < N) { mtx_lock(&mut); values_sum += i; mtx_unlock(&mut); } } return thrd_success; }
“Threading is a performance hack- Eric S. Raymond, 2003 ”
Communicating Sequential Processes
PROC foo (CHAN INT out!) out ! 42 : !PROC bar (CHAN INT in?) INT v: SEQ in ? v :
Em Go
• Processos = goroutines
• Canais = canais :)
goroutines ping-pongfunc play(msg string) { for { fmt.Println(msg) time.Sleep(100e6) } } !func main() { go play("ping") go play("pong") time.Sleep(2e9) }
Canais
type Person struct { Name string } !type Elevator struct { number int people chan Person }
Canaisfunc main() { nPeople := flag.Int("people", 100, "Number of people") nElevators := flag.Int("elevators", 4, "Number of elevators") flag.Parse() people := make(chan Person) for i := 0; i < *nElevators; i++ { e := NewElevator(i, people) e.Start() } for i := 0; i < *nPeople; i++ { name := fmt.Sprintf("person %d", i+1) people <-‐ Person{Name: name} } close(people) }
Canais
func (e *Elevator) Start() { go func() { for p := range e.people { fmt.Printf("elevator %d transporting %s.\n", e.number, p.Name) time.Sleep(time.Duration((rand.Int()%5 + 1) * 1e9)) } }() }
select
selectfunc elevator(name string) chan<-‐ Person { people := make(chan Person) go func() { for p := range people { fmt.Printf("Elevator %q transporting %q...\n", name, p.Name) time.Sleep(1e9) } }() return people }
select people := []Person{ {Name: "Bob"}, {Name: "Mary"}, {Name: "Thomas"}, {Name: "John"}, {Name: "Peter"}, {Name: "Ken"}, {Name: "Patricia"}, {Name: "Ane"}, {Name: "Alice"}, } elevator1 := elevator("social1") elevator2 := elevator("social2") elevator3 := elevator("vip") for _, person := range people { select { case elevator1 <-‐ person: case elevator2 <-‐ person: case elevator3 <-‐ person: } }
timeout
respChan := make(chan []byte) go doSomethingInTheNetwork(respChan) select { case data := <-‐respChan: // do something with data case time.After(5 * time.Second): fmt.Println(“sloooow connection”) }
quit go func() { conn := r.pool.Get() defer conn.Close() var payload interface{} var err error for payload == nil { select { case <-‐quit: return default: payload, err = conn.Do("RPOP", r.key()) if err != nil { errChan <-‐ err return } } } payloadChan <-‐ payload.([]byte) }()
quit + timeout
var payload []byte select { case payload = <-‐payloadChan: case err := <-‐errChan: return nil, err case <-‐time.After(timeout): close(quit) return nil, &timeoutError{timeout: timeout} }
Sincronização
• Mutex
• RWMutex
• Once
• WaitGroup
Once
var once sync.Once ... once.Do(func() { CreateDatabasePoll("localhost:27107", "db") })
WaitGroup• “fork-join"
var containersGroup sync.WaitGroup for _, container := range containers { containersGroup.Add(1) go collectUnit(container, units, &containersGroup) } containersGroup.Wait()
Operações atômicas
Paralelismo: Implícito x Explícito
• Concorrência: forma como você estrutura seu programa
• Paralelismo: forma como você executa seu programa
GOMAXPROCS
• Nível de paralelismo definido em tempo de execução
• runtime.GOMAXPROCS
• env GOMAXPROCS
Concorrência e Paralelismo em GoFrancisco Souza @franciscosouza [email protected]