xxxxxxxxxx
// if you use channel inside gorutine can't use defer in wg
// because this is deadlock, because channel is async process
// if you use channel, for better experience pass channel into params gorutine
package main
import (
"fmt"
"sync"
)
func main() {
wg := sync.WaitGroup{}
ch := make(chan int)
wg1 := sync.WaitGroup{}
slc := []int{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(chInt chan int) {
wg.Done()
chInt <- i
}(ch)
}
wg.Wait()
for i := 0; i < 5; i++ {
wg1.Add(1)
go func() {
defer wg1.Done()
slc = append(slc, i)
}()
}
wg1.Wait()
fmt.Println(<-ch)
fmt.Println(slc)
}
xxxxxxxxxx
// When we send data into the channel using a GoRoutine,
// it will be blocked until the data is consumed by another GoRoutine.
// When we receive data from channel using a GoRoutine,
// it will be blocked until the data is available in the channel.
func main() {
runIncrement()
}
func runIncrement() {
channel := make(chan string)
go increment(channel)
time.Sleep(1 * time.Second)
for msg := range channel {
fmt.Println(msg)
}
}
func increment(channel chan string) {
for i := 0; i < 3; i++ {
channel <- "Hello Wordl"
}
time.Sleep(1 * time.Second)
close(channel)
}
func runCounter() {
channel := make(chan string)
wg := sync.WaitGroup{}
wg.Add(1)
go counter(channel, &wg)
for msg := range channel {
fmt.Println(msg)
}
wg.Wait()
}
func counter(channel chan string, wg *sync.WaitGroup) {
for i := 0; i < 3; i++ {
channel <- "Hello world"
}
wg.Done()
close(channel)
}
xxxxxxxxxx
package main
import (
"fmt"
"time"
)
func main() {
channelImmutable()
}
// -> you use only allow one channel capacity, but you use 2 capacity, channel can be blocked
// for handle this issue, you must create channel to zero value, like this <- ch
func channelImmutable() {
ch := make(chan string, 1)
ch <- "marwan"
<-ch
ch <- "jajang"
fmt.Println("channelOne", <-ch) // and i can print jajang not marwan and this can't be blocked
}
// channelOne print value, with declare to variable channel;
func channelOne() {
ch := make(chan string, 2)
ch <- "marwan"
ch <- "jajang"
fmt.Println("channelOne", <-ch)
fmt.Println("channelOne", <-ch)
}
// channelTwo print value and wrapper with gorutine, because with you use loop range not using gorutine channel is blocked, because you print more channel
func channelTwo() {
ch := make(chan string, 2)
ch <- "marwan"
ch <- "jajang"
go func() {
for v := range ch {
fmt.Println(v)
}
}()
time.Sleep(time.Second * 1)
}
// channelThree print value without gorutine, but with loop and length channel
func channelThree() {
ch := make(chan string, 2)
ch <- "marwan"
ch <- "jajang"
for i := 0; i <= len(ch); i++ {
fmt.Println(<-ch)
}
}
xxxxxxxxxx
package main
import (
"errors"
"fmt"
"log"
"time"
)
// anda dapat mencetak nilai setelah gorutine itu selesai process nya, ganti time.Sleep dengan sync.WaitGroup
func main() {
SuccessOne()
}
func SuccessOne() {
resChan := make(chan string, 1)
errChan := make(chan error, 1)
go func(chRes chan string, chErr chan error) {
perkalian := 2 * 2
if perkalian == 4 {
chRes <- "Success"
} else {
chErr <- errors.New("Failed")
}
}(resChan, errChan)
time.Sleep(time.Second * 1)
select {
case err := <-errChan:
if err != nil {
log.Fatal(err)
}
case res := <-resChan:
if res != "" {
fmt.Println(res)
}
default:
fmt.Println("Not received channel")
}
}
func SuccessTwo() {
resChan := make(chan string, 1)
errChan := make(chan error, 1)
go func(chRes chan string, chErr chan error) {
perkalian := 2 * 2
if perkalian == 4 {
defer close(chErr)
chRes <- "Success"
} else {
defer close(chRes)
chErr <- errors.New("Failed")
}
}(resChan, errChan)
time.Sleep(time.Second * 1)
if err := <-errChan; err != nil {
log.Fatal(err)
}
fmt.Println(<-resChan)
}
func SuccessThree() {
resChan := make(chan string, 1)
errChan := make(chan error, 1)
go func(chRes chan string, chErr chan error) {
perkalian := 2 * 2
if perkalian == 4 {
chErr <- nil
chRes <- "Success"
} else {
chRes <- ""
chErr <- errors.New("Failed")
}
}(resChan, errChan)
time.Sleep(time.Second * 1)
if err := <-errChan; err != nil {
log.Fatal(err)
}
fmt.Println(<-resChan)
}
// dikarenakan perkalian nilainya sama dengan 4 dan chRes menerima nilai success,
// tetapi chErr tidak menerima nilai dan ini mengakibatkan chErr melakukan pemblokiran, karena channel nya selalu open dan nilainya kosong
// jadi dia harus di tutup atau di beri nilai atau menugnakan select untuk memilih channel mana yang memiliki nilai, untuk menghindari pemblokiran
func WrongCode() {
resChan := make(chan string, 1)
errChan := make(chan error, 1)
go func(chRes chan string, chErr chan error) {
perkalian := 2 * 2
if perkalian == 4 {
chRes <- "Success"
} else {
chErr <- errors.New("Failed")
}
}(resChan, errChan)
time.Sleep(time.Second * 1)
if err := <-errChan; err != nil {
log.Fatal(err)
}
fmt.Println(<-resChan)
}
xxxxxxxxxx
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string, 1)
go func(chStr chan string) {
chStr <- "Fuck Israel"
}(ch)
go func(chStr chan string) {
fmt.Println(<-chStr)
chStr <- "Free Palestine"
}(ch)
time.Sleep(time.Second * 1)
fmt.Println(<-ch)
}