完善gring包,增加约瑟夫问题代码作为gring示例程序

This commit is contained in:
john 2018-09-07 17:48:19 +08:00
parent 68a1a59f3a
commit 0cec53fe8d
6 changed files with 112 additions and 18 deletions

View File

@ -145,10 +145,10 @@ func (r *Ring) Unlink(n int) *Ring {
return r
}
// 往后只读遍历回调函数返回true表示继续遍历否则退出遍历
// 读锁遍历,往后只读遍历回调函数返回true表示继续遍历否则退出遍历
func (r *Ring) RLockIteratorNext(f func(value interface{}) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
r.mu.RLock(true)
defer r.mu.RUnlock(true)
if !f(r.ring.Value) {
return
}
@ -159,10 +159,10 @@ func (r *Ring) RLockIteratorNext(f func(value interface{}) bool) {
}
}
// 往前只读遍历回调函数返回true表示继续遍历否则退出遍历
// 读锁遍历,往前只读遍历回调函数返回true表示继续遍历否则退出遍历
func (r *Ring) RLockIteratorPrev(f func(value interface{}) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
r.mu.RLock(true)
defer r.mu.RUnlock(true)
if !f(r.ring.Value) {
return
}
@ -173,10 +173,10 @@ func (r *Ring) RLockIteratorPrev(f func(value interface{}) bool) {
}
}
// 往后写遍历回调函数返回true表示继续遍历否则退出遍历
// 写锁遍历,往后写遍历回调函数返回true表示继续遍历否则退出遍历
func (r *Ring) LockIteratorNext(f func(item *ring.Ring) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
r.mu.RLock(true)
defer r.mu.RUnlock(true)
if !f(r.ring) {
return
}
@ -187,10 +187,10 @@ func (r *Ring) LockIteratorNext(f func(item *ring.Ring) bool) {
}
}
// 往前写遍历回调函数返回true表示继续遍历否则退出遍历
// 写锁遍历,往前写遍历回调函数返回true表示继续遍历否则退出遍历
func (r *Ring) LockIteratorPrev(f func(item *ring.Ring) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
r.mu.RLock(true)
defer r.mu.RUnlock(true)
if !f(r.ring) {
return
}

View File

@ -7,11 +7,19 @@ import (
)
func main () {
// 创建一个对象池过期时间为1000毫秒
p := gpool.New(1000)
// 从池中取一个对象返回nil及错误信息
fmt.Println(p.Get())
// 丢一个对象到池中
p.Put(1)
// 重新从池中取一个对象返回1
fmt.Println(p.Get())
p.Put(2)
// 等待1秒后重试发现对象已过期返回nil及错误信息
time.Sleep(time.Second)
fmt.Println(p.Get())
}

View File

@ -0,0 +1,33 @@
package main
import (
"fmt"
"time"
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/container/gqueue"
)
func main() {
q := gqueue.New()
// 数据生产者每隔1秒往队列写数据
gtime.SetInterval(time.Second, func() bool {
v := gtime.Now().String()
q.PushBack(v)
fmt.Println("PushBack:", v)
return true
})
// 3秒后关闭队列
gtime.SetTimeout(3*time.Second, func() {
q.Close()
})
// 消费者,不停读取队列数据并输出到终端
for {
if v := q.PopFront(); v != nil {
fmt.Println("PopFront:", v)
} else {
break
}
}
}

View File

@ -0,0 +1,56 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/container/gring"
)
type Player struct {
position int // 位置
alive bool // 是否存活
}
const (
playerCount = 41 // 玩家人数
startPos = 1 // 开始报数位置
)
var (
deadline = 3
)
func main() {
// 关闭并发安全,当前场景没有必要
r := gring.New(playerCount, false)
// 设置所有玩家初始值
for i := 1; i <= playerCount; i++ {
r.Put(&Player{i, true})
}
// 如果开始报数的位置不为1则设置开始位置
if startPos > 1 {
r.Move(startPos - 1)
}
counter := 1 // 报数从1开始因为下面的循环从第二个开始计算
deadCount := 0 // 死亡人数初始值为0
// 直到所有人都死亡,否则循环一直执行
for deadCount < playerCount {
r.Next() // 跳到下一个人
// 如果是活着的人,则报数
if r.Val().(*Player).alive {
counter++
}
// 如果报数为deadline则此人淘汰出局
if counter == deadline {
r.Val().(*Player).alive = false
fmt.Printf("Player %d died!\n", r.Val().(*Player).position)
deadCount++
counter = 0
}
}
}

View File

@ -16,8 +16,5 @@ func main() {
fmt.Println(i.Val())
// (整型/浮点型有效)数值 增加/删除 delta
// 返回修改之前的数值
fmt.Println(i.Add(-1))
fmt.Println(i.Val())
}

View File

@ -1,7 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println(1)
}