GO: Paralelismo e concorrência
Diferenças entre concorrência e paralelismo
Na concorrência os processos são disparados ao mesmo tempo mas como é usado apenas um core, um processo vai parar para que o outro possa rodar e ai eles vão sendo intercalados.
No paralelismo os dois processos são iniciados ao mesmo tempo, mas cada um é processado em um core diferente do processador, fazendo assim com que os dois possam ser processados simultaneamente
고루틴
func main() {
runProcess("Process 1", 20)
runProcess("Process 2", 20)
}
func runProcess(name string, total int) {
for i := 0; i < total; i++ {
fmt.Println(name, i)
t := time.Duration(rand.Intn(255))
time.Sleep(time.Millisecond * t)
}
}
Essa função definida acima dessa forma inicial vai primeiro printar 20 vezes no terminal "Process 1"esperando semper um tempo aleatório em milissegundos para o segundo print, e depois vai printar mais 20 vezes "Process 2".
Adicionando um operator
go
na frente de cada uma da chamada das funções vai fazer com que ela rodem em paralelo e em background. Agora ao invés de esperarmos a primeira função rodar para só então a segunda ser executada, com o go
na frente enquanto uma função está esperando o timeout passar a outra é executada (se não definíssemos um timeout como é uma função muito simples na hora que o programa chegasse na segunda função a primeira já teria terminado de executar e não daria para ver o efeito da go 루틴)추가 기능
go
이 있습니다. Para resolver esse problema precisamos criar um waitGroup e para fazer com que o Go espere a função terminar de rodar para ai sim matar a aplicação.
var waitGroup sync.WaitGroup
func main() {
waitGroup.Add(2)
go runProcess("Process 1", 20)
go runProcess("Process 2", 20)
waitGroup.Wait()
}
func runProcess(name string, total int) {
for i := 0; i < total; i++ {
fmt.Println(name, i)
t := time.Duration(rand.Intn(255))
time.Sleep(time.Millisecond * t)
}
waitGroup.Done()
}
No main adicionei duas funções ao waitGroup e na função runProcess falo que o waitGroup concluiu o trabalho depois do for.
Mas agora fica a questão, o Go está usando paralelismo ou concorrência? e na verdade dependse, nesse caso é paralelismo pois tenho uma CPU de 6 cores então por default ele associa cada função a um core, porem se eu tivesse apenas 1 core no processorador ele rodaria as duas funções de forma concorrente
podemos testar também rodar de forma concorrente adicionando uma função init e setando o numero máximo de cores que permitimos o GO usar. porem se fizermos isso para esse caso o output será o mesmo
func init() {
runtime.GOMAXPROCS(1)
}
경쟁 조건
Race Conditions é um tipo de problemas que temos com o pararelismo onde a execução dos codigos em pararelo compromete de alguma forma as regras de negocio da aplicação, então por exemplo caso eu queira executar o total de vezes que o for rodou
var result int
var waitGroup sync.WaitGroup
func main() {
waitGroup.Add(2)
go runProcess("Process 1", 20)
go runProcess("Process 2", 20)
waitGroup.Wait()
fmt.Println("Result:", result)
}
func runProcess(name string, total int) {
for i := 0; i < total; i++ {
z := result
z++
t := time.Duration(rand.Intn(255))
time.Sleep(time.Millisecond * t)
result = z
fmt.Println(name, "->", i, result)
}
waitGroup.Done()
}
no meu println com mostrando o result que deveria ser 40 na verdade o output vai ser 20 e podemos ver que o valor de result de fato está sendo reatribuindo para um valor anterior constantemente por causa da execução anterior ainda não ter o novo valor que result deveria 터
se rodarmos o programa com
go run -race main.go
o proprio go já detecta se está ocorrendo uma race condition e se sim em quais linhaspara resolver o problema de race condition é bem simples basta usarmos o Mutex onde travamos uma operação até ela terminar de rodar para impedir que ela seja sobescrita no meio
func runProcess(name string, total int) {
for i := 0; i < total; i++ {
t := time.Duration(rand.Intn(255))
time.Sleep(time.Millisecond * t)
m.Lock()
result++
fmt.Println(name, "->", i, "total", result)
m.Unlock()
}
waitGroup.Done()
}
Agora os processos ficam travados esperando o result terminar de aumentar o seu valor, e só quando dou o unlock eles continuam. Se rodarmos a aplicação detectando race conditions podemos ver que agora nada foi detectado
Reference
이 문제에 관하여(GO: Paralelismo e concorrência), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/yanpiing/go-paralelismo-e-concorrencia-4mlo텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)