Skip to content

Instantly share code, notes, and snippets.

@gmailzj
Last active July 7, 2020 09:14
Show Gist options
  • Save gmailzj/4c1172ea1f291c067327435738b74113 to your computer and use it in GitHub Desktop.
Save gmailzj/4c1172ea1f291c067327435738b74113 to your computer and use it in GitHub Desktop.
work
package main
import (
"fmt"
"sync"
)
func main() {
list := []int{0, 1, 2, 3, 4}
sizes := make(chan int)
var wg sync.WaitGroup
for e := range list {
wg.Add(1)
go func(e int) {
defer wg.Done()
sizes <- e
}(e)
}
go func() {
wg.Wait()
close(sizes)
}()
var total int
for num := range sizes {
total += num
}
fmt.Println(total)
}
package main
import (
"fmt"
"time"
)
func main() {
var ch = make(chan string, 2)
go func() {
for i := 0; i < 5; i++ {
time.Sleep(500 * time.Millisecond)
ch <- "hello"
}
close(ch)
}()
for recv := range ch {
fmt.Println(recv)
}
}
package main
import (
"fmt"
"os"
"time"
)
func main() {
// select是一种多路复用技术,就像POSIX接口里的select可以同时对多个文件描述符进行监控一样,go提供的select可以同时对多个channel进行监控,实现并发接收。当多个case里的channel同时有数据ready的时候,select会随机选择一个case进行处理。
// 需要注意的是,range操作可以在channel关闭后自动退出,而select不会。所以在用for循环搭配select实现轮询时,select的case语句中必须显示的判断channel是否已经关闭,并做相应的处理,否则select每次从处于closed状态的channel中取出空值,并且继续执行case语句包含的body,程序的运行就可能与期望不一致。
var ch = make(chan string, 2)
go func() {
for i := 0; i < 5; i++ {
time.Sleep(1000 * time.Millisecond)
ch <- "hello"
}
close(ch)
}()
for {
select {
case recv, ok := <-ch:
if !ok {
os.Exit(0)
}
fmt.Println(recv)
}
}
}
package main
import (
"fmt"
"time"
"math/rand"
)
func main() {
ch := make(chan string)
count := 3
for index := 0; index < count; index++ {
go func() {
time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond)
ch <- "hello"
}()
}
for index := 0; index < count; index++ {
fmt.Println(<-ch)
}
time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond)
}
package main
import (
"fmt"
"strconv"
"math/rand"
"time"
)
type Message struct {
Id int
Name string
}
func main() {
messages := make(chan Message, 100)
result := make(chan error, 100)
// 创建任务处理Worker
for i := 0; i < 3; i ++ {
go worker(i, messages, result)
}
total := 0
// 发布任务
for k := 1; k <= 10; k ++ {
messages <- Message{Id: k, Name: "job" + strconv.Itoa(k)}
total += 1
}
close(messages)
// 接收任务处理结果
for j := 1; j <= total; j ++ {
res := <-result
if res != nil {
fmt.Println(res.Error())
}
}
close(result)
}
func worker(worker int, msg <-chan Message, result chan<- error) {
// 从通道 chan Message 中监听&接收新的任务
for job := range msg {
fmt.Println("worker:", worker, "msg: ", job.Id, ":", job.Name)
// 模拟任务执行时间
time.Sleep(time.Second * time.Duration(RandInt(1, 3)))
// 通过通道返回执行结果
result <- nil
}
}
func RandInt(min, max int) int {
rand.Seed(time.Now().UnixNano())
return min + rand.Intn(max-min+1)
}
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var mutex sync.Mutex
wait := sync.WaitGroup{}
fmt.Println("Locked")
mutex.Lock()
for i := 1; i <= 3; i++ {
wait.Add(1)
go func(i int) {
fmt.Println("Not lock:", i)
mutex.Lock()
fmt.Println("Lock:", i)
time.Sleep(time.Second)
fmt.Println("Unlock:", i)
mutex.Unlock()
defer wait.Done()
}(i)
}
time.Sleep(time.Second)
fmt.Println("Unlocked")
mutex.Unlock()
wait.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment