Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: tvojtatko 20. 08. 2019, 11:06:51
-
Mam tento priklad:
package main
import (
"fmt"
"time"
)
func greet(c chan string) {
println("blocking")
val, ok := <- c
println(val)
println(ok)
println("waiting")
val2, ok2 := <- c
println(val2)
println(ok2)
println("ending")
}
func main() {
c := make(chan string)
go greet(c)
time.Sleep(5000 * time.Millisecond)
c <- "John"
c <- "Jim"
}
vystup je
blocking
John
true
waiting
Jim
true
ending
Takze sa spusti go rutina greet(), prvy <- c je blokujuci, poslem c <- John, odblokuje sa to a vypise, poslem druhy krat c <- Jim, odblokuje sa to tiez a skonci sa program.
Problem je, ze bez toho time.Sleep(5000 * time.Millisecond) po go greet(c) sa vypise len John ale nie Jim.
Preco to tak je?
Ved greet ma v sebe dva blokujuce <- c, preco ked tam nedam ten time.Sleep, tak to vypise len John-a a skonci sa program a Jim sa akokeby odignoruje?
-
Tak odpoved je, ze ten channel mam unbuffered, takze cokolvek tam poslem cez c <- tak to nebude cakat, kym to niekto precita, takze sa stihne poslat John, to sa vypise, posle sa Jim a program skonci bez toho aby to doplavalo k druhemu <- c v greet.
Ked deklarujem channel s kapacitou 1, tak to vypise aj bez sleepu.
Na druhej strane ale nechapem, co s tym ma ten sleep spolocny, ze to zrazu vypise spravne, ked je ten channel unbuffered.
-
Tak odpoved je, ze ten channel mam unbuffered, takze cokolvek tam poslem cez c <- tak to nebude cakat, kym to niekto precita, takze sa stihne poslat John, to sa vypise, posle sa Jim a program skonci bez toho aby to doplavalo k druhemu <- c v greet.
Ked deklarujem channel s kapacitou 1, tak to vypise aj bez sleepu.
Na druhej strane ale nechapem, co s tym ma ten sleep spolocny, ze to zrazu vypise spravne, ked je ten channel unbuffered.
Unbuffered naopak čeká.
-
Tak v první řadě si musíš ujasnit, že program nečeká na ukončení všech gorutin - zkus si to:
https://play.golang.org/p/EWb7EBbneQk
Čili za druhé: tvoje otázka "proč mi to (ne)vypsalo?" by vůbec neměla být zkoumána, protože pokud na dokončení gorutiny explicitně nepočkáš, pak je chování programu náhodné (nedefinované). Může něco vypsat a nemusí z definice. Vůbec nezkoumej, kdy ano a kdy ne. Pokud chceš na dokončení gorutiny počkat, udělej to (viz např. https://stackoverflow.com/a/32383393). Pokud čekat nechceš, očekávej libovolný výsledek.
P.S. hodnoty z channelu se typicky zpracovávají pomocí range. Jiné řešení dává smysl málo kdy.
-
Tak v první řadě si musíš ujasnit, že program nečeká na ukončení všech gorutin - zkus si to:
https://play.golang.org/p/EWb7EBbneQk
na tyhle experimenty se hodí https://golang.org/pkg/runtime/#Goexit
https://play.golang.org/p/sEefsqrZNPR
-
na tyhle experimenty se hodí https://golang.org/pkg/runtime/#Goexit
https://play.golang.org/p/sEefsqrZNPR
To je super, to jsem neznal. Dík za tip!
-
Tak v první řadě si musíš ujasnit, že program nečeká na ukončení všech gorutin - zkus si to:
https://play.golang.org/p/EWb7EBbneQk
na tyhle experimenty se hodí https://golang.org/pkg/runtime/#Goexit
https://play.golang.org/p/sEefsqrZNPR
Akorát zrovna na hlavním vlákně dělá Goexit neplechu.
-
Akorát zrovna na hlavním vlákně dělá Goexit neplechu.
Jakou?
-
Akorát zrovna na hlavním vlákně dělá Goexit neplechu.
Jakou?
Viz dokumentace z odkazu výše. (“If all other goroutines exit, the program crashes.”)
-
Viz dokumentace z odkazu výše. (“If all other goroutines exit, the program crashes.”)
To jsem pochopil jako "zamer ne neplechu" ("feature not a bug" ;) ).
-
Viz dokumentace z odkazu výše. (“If all other goroutines exit, the program crashes.”)
To jsem pochopil jako "zamer ne neplechu" ("feature not a bug" ;) ).
Aha. Na mě to působí jako vedlejší efekt toho, když to někdo zavolá na hlavním vlákně. Ale pro experimenty asi dobrý, disk to nejspíš nemaže...
-
Viz dokumentace z odkazu výše. (“If all other goroutines exit, the program crashes.”)
To jsem pochopil jako "zamer ne neplechu" ("feature not a bug" ;) ).
BTW jak jde učení závislostních typů?
-
Aha. Na mě to působí jako vedlejší efekt toho, když to někdo zavolá na hlavním vlákně. Ale pro experimenty asi dobrý, disk to nejspíš nemaže...
Ja kdyz jsem to cetl, tak mi blesklo hlavou, ze to nejspis bude proto, ze by se nevedelo, jakej se ma z programu vratit navratovej kod. Ale to bude asi spis blbost :)
BTW jak jde učení závislostních typů?
Precetl jsem asi padesat stranek a pak jsem to musel odlozit kvuli jinym povinnostem a obavam se, ze az se k tomu vratim, tak budu muset zacit zas od zacatku, pac mezi tim detaily zapomenu :)
Ta knizka je stylove teda hodne zajimava :) ale nemuzu rict, ze by mi to uplne skvele vyhovovalo. Je to trosku moc rozvlacny na muj vkus. Uprednostnil bych o malicko min taskaric a vic vyklad k veci. Idealni mi prijde uroven taskaric, kterou ma Learn You Some (Erlang|Haskell) for Great Good!
-
Aha. Na mě to působí jako vedlejší efekt toho, když to někdo zavolá na hlavním vlákně. Ale pro experimenty asi dobrý, disk to nejspíš nemaže...
Ja kdyz jsem to cetl, tak mi blesklo hlavou, ze to nejspis bude proto, ze by se nevedelo, jakej se ma z programu vratit navratovej kod. Ale to bude asi spis blbost :)
Podle mě to je fakt jen vedlejší efekt, scheduleru prostě dojdou korutiny, což vyhodnotí jako deadlock a chcípne.
-
Podle mě to je fakt jen vedlejší efekt, scheduleru prostě dojdou korutiny, což vyhodnotí jako deadlock a chcípne.
Asi mas pravdu. Ale kdyby chteli, tak by scheduler v tehle situaci klidne mohl udelat exit(0), ze :)
-
BTW jak jde učení závislostních typů?
Precetl jsem asi padesat stranek a pak jsem to musel odlozit kvuli jinym povinnostem a obavam se, ze az se k tomu vratim, tak budu muset zacit zas od zacatku, pac mezi tim detaily zapomenu :)
Ta knizka je stylove teda hodne zajimava :) ale nemuzu rict, ze by mi to uplne skvele vyhovovalo. Je to trosku moc rozvlacny na muj vkus. Uprednostnil bych o malicko min taskaric a vic vyklad k veci. Idealni mi prijde uroven taskaric, kterou ma Learn You Some (Erlang|Haskell) for Great Good!
Ten styl je dost stupidní, rozhodně je mnohem lepší přečíst si radši něco o Heytingových algebrách a pak jen “přepnout” do FP.
-
Ten styl je dost stupidní, rozhodně je mnohem lepší přečíst si radši něco o Heytingových algebrách a pak jen “přepnout” do FP.
Silne pochybuju, ze by tohle byla dobra cesta pro me :)))
Mne ten styl nevadi, jenom bych ho trochu zhustil no.
-
Podle mě to je fakt jen vedlejší efekt, scheduleru prostě dojdou korutiny, což vyhodnotí jako deadlock a chcípne.
Asi mas pravdu. Ale kdyby chteli, tak by scheduler v tehle situaci klidne mohl udelat exit(0), ze :)
Asi ne, oni mají funkci pro obecnou kontrolu deadlocku, je jedno, jestli je korutin milion nebo nula, deadlock je prostě deadlock (z definice). Mohli by přidat další test na počet korutin, ale spíš nechtějí, aby se to používalo, protože na hlavní vlákno patří synchronizace. Taky by hlavní vlákno mohlo čekat implicitně. Možností (špatných) je jistě bambilion.
-
Taky by hlavní vlákno mohlo čekat implicitně. Možností (špatných) je jistě bambilion.
To by mi prislo jako nejlepsi reseni. Minimalne by odpadly zmateni/dotazy jako byl tenhle...
...zas ale na druhou stranu by se objevily novy dotazy typu "nekde mi visi nejaka corutina, jak zjistim, ktera to je?". To si nevyberes :)
-
Taky by hlavní vlákno mohlo čekat implicitně. Možností (špatných) je jistě bambilion.
To by mi prislo jako nejlepsi reseni. Minimalne by odpadly zmateni/dotazy jako byl tenhle...
...zas ale na druhou stranu by se objevily novy dotazy typu "nekde mi visi nejaka corutina, jak zjistim, ktera to je?". To si nevyberes :)
Mně osobně by se líbil u korutin join jako na vláknech.
-
Mně osobně by se líbil u korutin join jako na vláknech.
Jako každou druhou trivialitu si to musíš napsat sám pomocí sync.WaitGroup :)
-
Mně osobně by se líbil u korutin join jako na vláknech.
Jako každou druhou trivialitu si to musíš napsat sám pomocí sync.WaitGroup :)
No dyť právě.
-
No dyť právě.
Pořád lepší než https://stackoverflow.com/a/50487104/3150343 :))