【goroutine的一种使用方法】参考网上资料自己写的,可以运行,但是因为没找到类似的教程,只是自己想着写的,供大家参考,如果有错误,也请大家提出
主要逻辑就是一个聊天室房间,并发的向该房间增加、删除用户
package mainimport (
"log"
"math/rand"
"os"
"os/signal"
"runtime"
"syscall"
)type Room struct {
chchan *User
usersmap[int]*User
userIdint
running bool
}type User struct {
userId int
action string
result bool //该chan只用作阻塞ADD、DEL的routine
ch chan bool
}func NewRoom() *Room {
room := &Room{
ch:make(chan *User, 200),
users:make(map[int]*User, 2000),
userId:0,
running: true,
}
go room.beginListen()
return room
}func (room *Room) beginListen() {
var user *User
var ok bool
for room.running {
user, ok = <-room.ch
if ok {
if user.action == "DEL" {
_, ok := room.users[user.userId]
if ok {
delete(room.users, user.userId)
user.result = true
log.Println("DEL, user num", len(room.users))
} else {
user.result = false
}
} else if user.action == "ADD" {
user.userId = room.userId
room.userId++
room.users[user.userId] = user
user.result = true
log.Println("ADD, user num", len(room.users))
}
//执行完成后,关闭user的ch,唤醒user的routine
close(user.ch)
} else {
log.Println("Exit Room routine")
break
}
}
}func (room *Room) closeRoom() {
room.running = false
close(room.ch)
}func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) room := NewRoom()
for i := 0;
i < 100;
i++ {
go addUser(room)
go delUser(room)
} ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
log.Println("signal:", <-ch)
room.closeRoom()
}//下面两个方法模拟多个线程并发操作
func addUser(room *Room) {
for {
user := &User{ch: make(chan bool), action: "ADD"}
room.ch <- user
//通过下面一句阻塞routine,等待room中执行ADD完成,通过关闭user的ch重新唤醒该routine
<-user.ch
log.Println("ADD user", user.result)
}
}func delUser(room *Room) {
for {
user := &User{userId: rand.Intn(999), ch: make(chan bool), action: "DEL"}
room.ch <- user
//通过下面一句阻塞routine,等待room中执行DEL完成,通过关闭user的ch重新唤醒该routine
<-user.ch
log.Println("DEL user", user.result)
}
}
推荐阅读
- 【golang】leetcode中级-字母异位词分组&无重复字符的最长子串
- 彻底理解Golang Map
- kratos线上开源年会它来啦~
- 深入浅出 Golang 资源嵌入方案(go-bindata篇)
- 深入浅出 Golang 资源嵌入方案(前篇)
- golang 经典案例总结
- Go实战 | 基于有向无环图的并发执行流的实现
- Golang 数组和切片
- Go JSON编码与解码()
- golang map基础知识