Skip to content

Instantly share code, notes, and snippets.

@hyper0x
Last active July 21, 2020 21:14
Show Gist options
  • Save hyper0x/85d082e83b35122ca53e to your computer and use it in GitHub Desktop.
Save hyper0x/85d082e83b35122ca53e to your computer and use it in GitHub Desktop.
The hot replacement method of Golang's Channel
package main
import (
"fmt"
"sync"
"time"
)
const CHANGE_SIGN = -1 // The last element of the useless chan1
var chan1 chan int
var chanLength int = 18
var interval time.Duration = 1500 * time.Millisecond
var rwmutex sync.RWMutex // The mutex for protect chan1
func main() {
chan1 = make(chan int, chanLength)
go func() {
for i := 0; i < chanLength; i++ {
if i > 0 && i%3 == 0 {
rwmutex.Lock()
fmt.Println("Reset chan1...")
chan1 <- CHANGE_SIGN
chan1 = make(chan int, chanLength)
rwmutex.Unlock()
}
fmt.Printf("Send element %d...\n", i)
getChan() <- i
time.Sleep(interval)
}
fmt.Println("Close chan1...")
close(chan1)
}()
receive()
}
func receive() {
fmt.Println("Begin to receive elements from chan1...")
timer := time.After(30 * time.Second)
Loop:
for {
chan2 := getChan()
select {
case e, ok := <-chan2:
if !ok {
fmt.Println("--chan1 closed.")
break Loop
}
if e == CHANGE_SIGN {
close(chan2)
continue
}
fmt.Printf("Received an element: %d\n", e)
time.Sleep(interval)
case <-timer:
fmt.Println("Timeout!")
break Loop
}
}
fmt.Println("--End.")
}
func getChan() chan int {
rwmutex.RLock()
defer rwmutex.RUnlock()
return chan1
}
package main
import (
"fmt"
"time"
)
var chan1 chan int
var chanLength int = 18
var interval time.Duration = 1500 * time.Millisecond
func main() {
chan1 = make(chan int, chanLength)
go func() {
for i := 0; i < chanLength; i++ {
if i > 0 && i%3 == 0 {
fmt.Println("Reset chan1...")
chan1 = make(chan int, chanLength)
}
fmt.Printf("Send element %d...\n", i)
chan1 <- i
time.Sleep(interval)
}
fmt.Println("Close chan1...")
close(chan1)
}()
receive()
}
func receive() {
fmt.Println("Begin to receive elements from chan1...")
timer := time.After(30 * time.Second)
Loop:
for {
select {
case e, ok := <-getChan():
if !ok {
fmt.Println("--chan1 closed.")
break Loop
}
fmt.Printf("Received an element: %d\n", e)
time.Sleep(interval)
case <-timer:
fmt.Println("Timeout!")
break Loop
}
}
fmt.Println("--End.")
}
func getChan() chan int {
return chan1
}
package main
import (
"fmt"
"time"
)
var chan1 chan int
var chanLength int = 18
var interval time.Duration = 1500 * time.Millisecond
func main() {
chan1 = make(chan int, chanLength)
go func() {
for i := 0; i < chanLength; i++ {
if i > 0 && i%3 == 0 {
go func() {
fmt.Println("Reset chan1...")
chan1 = make(chan int, chanLength)
}()
}
fmt.Printf("Send element %d...\n", i)
chan1 <- i
time.Sleep(interval)
}
fmt.Println("Close chan1...")
close(chan1)
}()
receive()
}
func receive() {
fmt.Println("Begin to receive elements from chan1...")
timer := time.After(30 * time.Second)
Loop:
for {
select {
case e, ok := <-getChan():
if !ok {
fmt.Println("--chan1 closed.")
break Loop
}
fmt.Printf("Received an element: %d\n", e)
time.Sleep(interval)
case <-timer:
fmt.Println("Timeout!")
break Loop
}
}
fmt.Println("--End.")
}
func getChan() chan int {
return chan1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment