Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: tvojtatko 20. 08. 2019, 11:06:51

Název: Nechápem tuto Go rutinu
Přispěvatel: tvojtatko 20. 08. 2019, 11:06:51
Mam tento priklad:

Kód: [Vybrat]
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

Kód: [Vybrat]
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?
Název: Re:nechapem tuto go rutinu
Přispěvatel: tvojtatko 20. 08. 2019, 11:15:36
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.
Název: Re:nechapem tuto go rutinu
Přispěvatel: Idris 20. 08. 2019, 12:17:44
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á.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 20. 08. 2019, 13:09:53
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Tomáš Procházka 21. 08. 2019, 13:52:02
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
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 14:55:40
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!
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 17:50:27
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 17:51:40
Akorát zrovna na hlavním vlákně dělá Goexit neplechu.
Jakou?
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 17:59:59
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.”)
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 18:03:14
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" ;) ).
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 18:31:31
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...
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 18:32:27
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ů?
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 18:41:46
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!
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 18:43:49
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 18:45:23
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 :)
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 18:46:04
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 18:50:05
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 18:50:09
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 18:53:54
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 :)
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 20:31:03
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.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 20:36:57
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 :)
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Idris 21. 08. 2019, 20:49:04
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ě.
Název: Re:Nechápem tuto Go rutinu
Přispěvatel: Mirek Prýmek 21. 08. 2019, 21:13:20
No dyť právě.
Pořád lepší než https://stackoverflow.com/a/50487104/3150343 :))