Исходники и презентации
This commit is contained in:
38
lessons/channels/broadcast/main.go
Normal file
38
lessons/channels/broadcast/main.go
Normal file
@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func notifier(signals chan int) {
|
||||
close(signals)
|
||||
}
|
||||
|
||||
func subscriber(signals chan int) {
|
||||
<-signals
|
||||
fmt.Println("signaled")
|
||||
}
|
||||
|
||||
func main() {
|
||||
signals := make(chan int)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(3)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
notifier(signals)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
subscriber(signals)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
subscriber(signals)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
7
lessons/channels/buffered_channel/main.go
Normal file
7
lessons/channels/buffered_channel/main.go
Normal file
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
ch := make(chan int, 2)
|
||||
ch <- 100
|
||||
ch <- 100
|
||||
}
|
||||
21
lessons/channels/channel_data_race/main.go
Normal file
21
lessons/channels/channel_data_race/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "sync"
|
||||
|
||||
// go run -race main.go
|
||||
|
||||
var buffer chan int
|
||||
|
||||
func main() {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(100)
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
buffer = make(chan int)
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
21
lessons/channels/channel_interaction/main.go
Normal file
21
lessons/channels/channel_interaction/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Describe blocking
|
||||
|
||||
func async(ch chan string) {
|
||||
time.Sleep(2 * time.Second)
|
||||
ch <- "async result"
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch := make(chan string)
|
||||
go async(ch)
|
||||
// ...
|
||||
result := <-ch
|
||||
fmt.Println(result)
|
||||
}
|
||||
14
lessons/channels/copy_channel/main.go
Normal file
14
lessons/channels/copy_channel/main.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
source := make(chan int)
|
||||
clone := source
|
||||
|
||||
go func() {
|
||||
source <- 1
|
||||
}()
|
||||
|
||||
fmt.Println(<-clone)
|
||||
}
|
||||
46
lessons/channels/deadlock/main.go
Normal file
46
lessons/channels/deadlock/main.go
Normal file
@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var actions int
|
||||
var mutex sync.Mutex
|
||||
var buffer chan struct{}
|
||||
|
||||
func consumer() {
|
||||
for i := 0; i < 1000; i++ {
|
||||
mutex.Lock()
|
||||
actions++
|
||||
<-buffer
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func producer() {
|
||||
for i := 0; i < 1000; i++ {
|
||||
buffer <- struct{}{}
|
||||
mutex.Lock()
|
||||
actions++
|
||||
mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
buffer = make(chan struct{}, 1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
consumer()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
producer()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
26
lessons/channels/goroutine_leak_1/main.go
Normal file
26
lessons/channels/goroutine_leak_1/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
doWork := func(strings <-chan string) {
|
||||
go func() {
|
||||
for str := range strings {
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
||||
log.Println("doWork exited")
|
||||
}()
|
||||
}
|
||||
|
||||
strings := make(chan string)
|
||||
doWork(strings)
|
||||
strings <- "Test"
|
||||
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("Done")
|
||||
}
|
||||
15
lessons/channels/goroutine_leak_2/main.go
Normal file
15
lessons/channels/goroutine_leak_2/main.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
// Need to show solution and describe close
|
||||
|
||||
// First-response-wins strategy
|
||||
func request() int {
|
||||
ch := make(chan int)
|
||||
for i := 0; i < 5; i++ {
|
||||
go func() {
|
||||
ch <- i // 4 goroutines will be blocked
|
||||
}()
|
||||
}
|
||||
|
||||
return <-ch
|
||||
}
|
||||
22
lessons/channels/increment_with_channel/main.go
Normal file
22
lessons/channels/increment_with_channel/main.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ch := make(chan int)
|
||||
|
||||
go func() {
|
||||
ch <- 1
|
||||
}()
|
||||
go func() {
|
||||
ch <- 1
|
||||
}()
|
||||
|
||||
value := 0
|
||||
value += <-ch
|
||||
value += <-ch
|
||||
|
||||
fmt.Println(value)
|
||||
}
|
||||
27
lessons/channels/increment_with_mutex/main.go
Normal file
27
lessons/channels/increment_with_mutex/main.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mutex := sync.Mutex{}
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
value := 0
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
mutex.Lock()
|
||||
value++
|
||||
mutex.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
fmt.Println(value)
|
||||
}
|
||||
19
lessons/channels/is_closed_1/main.go
Normal file
19
lessons/channels/is_closed_1/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func IsClosed(ch chan int) bool {
|
||||
select {
|
||||
case <-ch:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch := make(chan int)
|
||||
fmt.Println(IsClosed(ch))
|
||||
close(ch)
|
||||
fmt.Println(IsClosed(ch))
|
||||
}
|
||||
22
lessons/channels/is_closed_2/main.go
Normal file
22
lessons/channels/is_closed_2/main.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Need to show solution
|
||||
|
||||
func IsClosed(ch chan int) bool {
|
||||
select {
|
||||
case <-ch:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch := make(chan int, 1)
|
||||
ch <- 1
|
||||
fmt.Println(IsClosed(ch))
|
||||
close(ch)
|
||||
fmt.Println(IsClosed(ch))
|
||||
}
|
||||
47
lessons/channels/nil_channel/main.go
Normal file
47
lessons/channels/nil_channel/main.go
Normal file
@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Need to show solution
|
||||
|
||||
func WaitToClose(lhs, rhs chan struct{}) {
|
||||
lhsClosed, rhsClosed := false, false
|
||||
for !lhsClosed || !rhsClosed {
|
||||
select {
|
||||
case _, ok := <-lhs:
|
||||
fmt.Println("lhs", ok)
|
||||
if !ok {
|
||||
lhsClosed = true
|
||||
}
|
||||
case _, ok := <-rhs:
|
||||
fmt.Println("rhs", ok)
|
||||
if !ok {
|
||||
rhsClosed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
lhs := make(chan struct{}, 1)
|
||||
rhs := make(chan struct{}, 1)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
WaitToClose(lhs, rhs)
|
||||
}()
|
||||
|
||||
lhs <- struct{}{}
|
||||
rhs <- struct{}{}
|
||||
|
||||
close(lhs)
|
||||
close(rhs)
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
19
lessons/channels/nil_channel_task/main.go
Normal file
19
lessons/channels/nil_channel_task/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
ch := make(chan int, 1)
|
||||
for done := false; !done; {
|
||||
select {
|
||||
default:
|
||||
fmt.Println(3)
|
||||
done = true
|
||||
case <-ch:
|
||||
fmt.Println(2)
|
||||
ch = nil
|
||||
case ch <- 1:
|
||||
fmt.Println(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
27
lessons/channels/non_blocking_channels_correct/main.go
Normal file
27
lessons/channels/non_blocking_channels_correct/main.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
func tryToReadFromChannel(ch chan string) (string, bool) {
|
||||
select {
|
||||
case value := <-ch:
|
||||
return value, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func tryToWriteToChannel(ch chan string, value string) bool {
|
||||
select {
|
||||
case ch <- value:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func tryToReadOrWrite(ch1 chan string, ch2 chan string) {
|
||||
select {
|
||||
case <-ch1:
|
||||
case ch2 <- "test":
|
||||
default:
|
||||
}
|
||||
}
|
||||
19
lessons/channels/non_blocking_channels_incorrect/main.go
Normal file
19
lessons/channels/non_blocking_channels_incorrect/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
func tryToReadFromChannel(ch chan string) (string, bool) {
|
||||
if len(ch) != 0 {
|
||||
value := <-ch
|
||||
return value, true
|
||||
} else {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func tryToWriteToChannel(ch chan string, value string) bool {
|
||||
if len(ch) < cap(ch) {
|
||||
ch <- value
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
91
lessons/channels/operations_with_channel/main.go
Normal file
91
lessons/channels/operations_with_channel/main.go
Normal file
@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func writeToNilChannel() {
|
||||
var ch chan int
|
||||
ch <- 1
|
||||
}
|
||||
|
||||
func writeToClosedChannel() {
|
||||
ch := make(chan int, 2)
|
||||
close(ch)
|
||||
ch <- 20
|
||||
}
|
||||
|
||||
// Descibe read after close
|
||||
|
||||
func readFromChannel() {
|
||||
ch := make(chan int, 2)
|
||||
ch <- 10
|
||||
ch <- 20
|
||||
|
||||
val, ok := <-ch
|
||||
fmt.Println(val, ok)
|
||||
|
||||
close(ch)
|
||||
val, ok = <-ch
|
||||
fmt.Println(val, ok)
|
||||
|
||||
val, ok = <-ch
|
||||
fmt.Println(val, ok)
|
||||
}
|
||||
|
||||
func readAnyChannels() {
|
||||
ch1 := make(chan int)
|
||||
ch2 := make(chan int)
|
||||
|
||||
go func() {
|
||||
ch1 <- 100
|
||||
}()
|
||||
|
||||
go func() {
|
||||
ch2 <- 200
|
||||
}()
|
||||
|
||||
select {
|
||||
case val1 := <-ch1:
|
||||
fmt.Println(val1)
|
||||
case val2 := <-ch2:
|
||||
fmt.Println(val2)
|
||||
}
|
||||
}
|
||||
|
||||
func readFromNilChannel() {
|
||||
var ch chan int
|
||||
<-ch
|
||||
}
|
||||
|
||||
func rangeNilChannel() {
|
||||
var ch chan int
|
||||
for range ch {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func closeNilChannel() {
|
||||
var ch chan int
|
||||
close(ch)
|
||||
}
|
||||
|
||||
func closeChannelAnyTimes() {
|
||||
ch := make(chan int)
|
||||
close(ch)
|
||||
close(ch)
|
||||
}
|
||||
|
||||
func compareChannels() {
|
||||
ch1 := make(chan int)
|
||||
ch2 := make(chan int)
|
||||
|
||||
equal1 := ch1 == ch2
|
||||
equal2 := ch1 == ch1
|
||||
|
||||
fmt.Println(equal1)
|
||||
fmt.Println(equal2)
|
||||
}
|
||||
|
||||
func main() {
|
||||
}
|
||||
33
lessons/channels/prioritization/main.go
Normal file
33
lessons/channels/prioritization/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Need to show solution
|
||||
|
||||
func producer(ch chan<- int) {
|
||||
for {
|
||||
ch <- 1
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch1 := make(chan int) // more prioritized
|
||||
ch2 := make(chan int)
|
||||
|
||||
go producer(ch1)
|
||||
go producer(ch2)
|
||||
|
||||
for {
|
||||
select {
|
||||
case value := <-ch1:
|
||||
fmt.Println(value)
|
||||
return
|
||||
case value := <-ch2:
|
||||
fmt.Println(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
27
lessons/channels/prioritization_weight/main.go
Normal file
27
lessons/channels/prioritization_weight/main.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
ch1 := make(chan struct{}, 1)
|
||||
ch2 := make(chan struct{}, 1)
|
||||
|
||||
close(ch1)
|
||||
close(ch2)
|
||||
|
||||
ch1Value := 0.0
|
||||
ch2Value := 0.0
|
||||
|
||||
for i := 0; i < 100000; i++ {
|
||||
select {
|
||||
case <-ch1:
|
||||
ch1Value++
|
||||
case <-ch1:
|
||||
ch1Value++
|
||||
case <-ch2:
|
||||
ch2Value++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(ch1Value / ch2Value)
|
||||
}
|
||||
51
lessons/channels/producer_consumer/main.go
Normal file
51
lessons/channels/producer_consumer/main.go
Normal file
@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func producer(ch chan int) {
|
||||
defer close(ch)
|
||||
for i := 0; i < 5; i++ {
|
||||
ch <- i
|
||||
}
|
||||
}
|
||||
|
||||
func consumer(ch chan int) {
|
||||
|
||||
/*
|
||||
for {
|
||||
select {
|
||||
case value, opened := <-ch:
|
||||
if !opened {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(value)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
for value := range ch { // syntax sugar
|
||||
fmt.Println(value)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch := make(chan int)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
producer(ch)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
consumer(ch)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
36
lessons/channels/select/main.go
Normal file
36
lessons/channels/select/main.go
Normal file
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func async1() chan string {
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
ch <- "async1 result"
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func async2() chan string {
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
ch <- "async2 result"
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch1 := async1()
|
||||
ch2 := async2()
|
||||
|
||||
select {
|
||||
case result := <-ch1:
|
||||
fmt.Println(result)
|
||||
case result := <-ch2:
|
||||
fmt.Println(result)
|
||||
}
|
||||
}
|
||||
29
lessons/channels/select_forever/main.go
Normal file
29
lessons/channels/select_forever/main.go
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
func way1() {
|
||||
make(chan struct{}) <- struct{}{}
|
||||
// or
|
||||
make(chan<- struct{}) <- struct{}{}
|
||||
}
|
||||
|
||||
func way2() {
|
||||
<-make(chan struct{})
|
||||
// or
|
||||
<-make(<-chan struct{})
|
||||
// or
|
||||
for range make(<-chan struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func way3() {
|
||||
chan struct{}(nil) <- struct{}{}
|
||||
// or
|
||||
<-chan struct{}(nil)
|
||||
// or
|
||||
for range chan struct{}(nil) {
|
||||
}
|
||||
}
|
||||
|
||||
func way4() {
|
||||
select {}
|
||||
}
|
||||
33
lessons/channels/select_with_break_and_continue/main.go
Normal file
33
lessons/channels/select_with_break_and_continue/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
data := make(chan int)
|
||||
go func() {
|
||||
for i := 1; i <= 4; i++ {
|
||||
data <- i
|
||||
}
|
||||
close(data)
|
||||
}()
|
||||
|
||||
for {
|
||||
value := 0
|
||||
opened := true
|
||||
|
||||
select {
|
||||
case value, opened = <-data:
|
||||
if value == 2 {
|
||||
continue
|
||||
} else if value == 3 {
|
||||
break
|
||||
}
|
||||
|
||||
if !opened {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(value)
|
||||
}
|
||||
}
|
||||
15
lessons/channels/select_with_main_goroutine/main.go
Normal file
15
lessons/channels/select_with_main_goroutine/main.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import "runtime"
|
||||
|
||||
func doSomething() {
|
||||
for {
|
||||
runtime.Gosched()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
go doSomething()
|
||||
go doSomething()
|
||||
select {}
|
||||
}
|
||||
38
lessons/channels/sequential_execution/main.go
Normal file
38
lessons/channels/sequential_execution/main.go
Normal file
@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Need to show solution
|
||||
|
||||
func FetchData1() chan int {
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
time.Sleep(time.Second * 2)
|
||||
ch <- 10
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
func FetchData2() chan int {
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
time.Sleep(time.Second * 2)
|
||||
ch <- 20
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
func Process(value1, value2 int) {
|
||||
// Processing...
|
||||
}
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
Process(<-FetchData1(), <-FetchData2())
|
||||
fmt.Println(time.Now().Sub(start))
|
||||
}
|
||||
33
lessons/channels/signals/main.go
Normal file
33
lessons/channels/signals/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func notifier(signals chan struct{}) {
|
||||
signals <- struct{}{}
|
||||
}
|
||||
|
||||
func subscriber(signals chan struct{}) {
|
||||
<-signals
|
||||
fmt.Println("signaled")
|
||||
}
|
||||
|
||||
func main() {
|
||||
signals := make(chan struct{})
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
notifier(signals)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
subscriber(signals)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
19
lessons/channels/unidirectional_channels/main.go
Normal file
19
lessons/channels/unidirectional_channels/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func in(in chan<- int) {
|
||||
in <- 100
|
||||
close(in)
|
||||
}
|
||||
|
||||
func out(out <-chan int) {
|
||||
fmt.Println(<-out)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var ch = make(chan int, 1)
|
||||
|
||||
in(ch)
|
||||
out(ch)
|
||||
}
|
||||
19
lessons/channels/write_after_close/main.go
Normal file
19
lessons/channels/write_after_close/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
ch <- 1
|
||||
}()
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
close(ch)
|
||||
<-ch
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
Reference in New Issue
Block a user