lxzan / gws

simple, fast, reliable websocket server & client, supports running over tcp/kcp/unix domain socket. keywords: ws, proxy, chat, go, golang...
https://pkg.go.dev/github.com/lxzan/gws
Apache License 2.0
1.36k stars 87 forks source link

哈哈,我还是没忍住 #43

Closed shaovie closed 1 year ago

shaovie commented 1 year ago
package main

import (
    "fmt"
    "time"
    "sync"
)

type (
    workerQueue struct {
        mu             sync.Mutex // 锁
        q              []asyncJob // 任务队列
        maxConcurrency int32      // 最大并发
        curConcurrency int32      // 当前并发
    }

    asyncJob func()
)

// newWorkerQueue 创建一个任务队列
func newWorkerQueue(maxConcurrency int32) *workerQueue {
    c := &workerQueue{
        mu:             sync.Mutex{},
        maxConcurrency: maxConcurrency,
        curConcurrency: 0,
    }
    return c
}

// 获取一个任务
func (c *workerQueue) getJob(delta int32) asyncJob {
    c.mu.Lock()
    defer c.mu.Unlock()

    c.curConcurrency += delta
    if c.curConcurrency >= c.maxConcurrency {
        return nil
    }
    if len(c.q) == 0 {
        return nil
    }
    var result = c.q[0]
    c.q = c.q[1:]
    c.curConcurrency++
    return result
}

// 循环执行任务
func (c *workerQueue) do(job asyncJob) {
    for job != nil {
        job()
        job = c.getJob(-1)
    }
}
// Push 追加任务, 有资源空闲的话会立即执行
func (c *workerQueue) Push(job asyncJob) {
    c.mu.Lock()
    c.q = append(c.q, job)
    c.mu.Unlock()
    if job := c.getJob(0); job != nil {
        go c.do(job)
    }
}

func main() {
    wq := newWorkerQueue(8)
    wq.Push(func () { fmt.Println(1) })
    wq.Push(func () { fmt.Println(2) })
    wq.Push(func () { fmt.Println(3) })
    wq.Push(func () { fmt.Println(4) })
    wq.Push(func () { fmt.Println(5) })
    wq.Push(func () { fmt.Println(6) })
    time.Sleep(time.Millisecond * 1000)
}
go run c.go
6
4
2
3
1
5

你看,我直接把task.go拷贝过来的,这总看明白了吧 ^_^

shaovie commented 1 year ago

快把我拉回去吧,

lxzan commented 1 year ago

昨天讨论的是写队列,并发度为1。读队列并发度为8,本来就有乱序问题,你看看这个README的输出 https://github.com/lxzan/concurrency

lxzan commented 1 year ago

快把我拉回去吧,

去找lesismal

lxzan commented 1 year ago
image
shaovie commented 1 year ago

哈哈,你看解决问题有这么麻烦吗,

我写示例代码之前 就搜过你的代码,不过我是用newWorkerQueue 搜的,没发现有初始化的地方,我就以为这个功能还没启动,你要发新版本启用这个功能 我这里也说明了,并发数量。。。

image

我都手写代码帮助你检查问题了,还被你们给踢出来了。。

顺便说一下 你这个ReadAsyncEnabled 换成 ParallelHandleMessageEnabled 是不是更合适?

你们对自己的代码肯定比我熟啊,你如果看了我写的代码,直接指出说“实际用的时候并发参数是1”,而不是说什么“强盗逻辑。。“啥的有的没有的,不就结了吗?

昨天讨论的是写队列,并发度为1。读队列并发度为8,本来就有乱序问题,你看看这个README的输出 https://github.com/lxzan/concurrency

我主动质疑个bug点,被你们搞的还人身攻击了。 我说啥了,你说我是强盗逻辑?兄弟,我是在帮你查bug哎,

lxzan commented 1 year ago

说过好几次写队列并发度为1,你不听有什么办法

image image image

命名那个,名字确实没取好。

lxzan commented 1 year ago

再说一点, 即使乱序也不是bug, 发送之前已经把消息帧拼装好了, net.TcpConn底层是有锁的.

shaovie commented 1 year ago

说过好几次写队列并发度为1,你不听有什么办法 image

image image 命名那个,名字确实没取好。

这已经是之后的消息了,而且 lesismal又起了个新话题,我以为你们在说他的问题就没细看

lxzan commented 1 year ago

你给我讲逻辑之前发的消息

shaovie commented 1 year ago

哈哈,周末多陪陪老婆孩子吧