BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / golang / #1439同步于 2019/5/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖

【问题】golang中如何实现一个无限长的Queue

Zelda
2019/5/16镜像同步22 回复
buffered channel的设计简直匪夷所思,什么“内存有限,无限长的队列不符合逻辑”的鬼话。简直是bullshit,逻辑上的queue就可以是无限大的,就像slice和map是“无限大”的一样。举例来说,当你需要多线程bfs的时候,一个无限大的queue就是必须的,因为程序无法预估图的规模。那么问题来了,如何在golang中实现一个无限大的、线程安全的、有Timeout的queue呢?我发现在Golang中实现一个有Timeout的queue特别麻烦,只能用很不优雅的workaround。主要原因在于Golang的sync.Cond竟然不支持类似pthread的pthread_cond_timedwait的方法。现在的workaround是一个双链表+两个channel+两个routine处理输入输出,在外部用select+ticker,才勉强实现了这个功能。在此想请教下有什么优雅的方法实现一个类似Python中queue.Queue的数据结构。 PS. 我真是服了,回复全是给Golang洗地的,说辞全是“需要无限长的Queue就是你程序有问题”,而没有一个回答问题的。 PPS. 大概实现了一个支持Timeout的Condition variable,但是非常简陋,并不能支持notify_all. ```Go type myCond struct { l *sync.Mutex ch chan bool } func (c *myCond) waitTimeout(timeout time.Duration) error { c.l.Unlock() defer c.l.Lock() select { case <-time.After(timeout): return fmt.Errorf("wait timeout") case <-c.ch: return nil } } func (c *myCond) wait() { c.l.Unlock() defer c.l.Lock() <-c.ch } func (c *myCond) notify() { select { case c.ch <- true: return default: return } } ```
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
ztinpn机器人#1 · 2019/5/16
已加入面试题题库
wanghaohebe机器人#2 · 2019/5/16
无限大的queue要有Timeout干嘛?内存有限,无限长的队列又有什么意义,给你实现了无界channel,你真能装无限的数据?有界channel才会让你思考该怎么设计使用,而不是无脑往队列里面塞东西直到内存爆掉。如果真要装超出内存的数据,就不应该再用简单的channel了
lance6716机器人#3 · 2019/5/16
mark
Zelda机器人#4 · 2019/5/16
我真是服了您这种Golang maniac/cultist。逻辑上的无穷和实际的无限大是一回事吗?您按照的您的思路回答一下,为什么slice可以不用限定最大容量?你要无脑往Slice里装超过内存的数据?有些情况根本没法预估问题的规模,比如BFS,这个时候当然需要一个逻辑上“无限大”的queue。 换个问法问您,Python的queue.Queue、Java的BlockingQueue都是没意义的?这些设计都是为了让人撑爆内存的? Golang大概是诞生于21世纪的语言中,技术品味最差的一个,还有一堆cultists无脑洗地,简直了…… 【 在 wanghaohebe 的大作中提到: 】 : 无限大的queue要有Timeout干嘛?内存有限,无限长的队列又有什么意义,给你实现了无界channel,你真能装无限的数据?有界channel才会让你思考该怎么设计使用,而不是无脑往队列里面塞东西直到内存爆掉。如果真要装超出内存的数据,就不应该再用简单的channel了
wanghaohebe机器人#5 · 2019/5/16
Python的queue.Queue、Java的BlockingQueue都不是语言层面的东西吧?你要是觉得这种无限大的队列有必要你可以自己写了往golang的标准库里面提交啊?你觉得你比golang的设计者还牛逼?逻辑上的无穷和实际的无限大不是一回事,就是要在设计上就不让没水平的代码导致实际的无限大。通过通信共享内存,不是让你用通信来撑爆内存的。你可以不喜欢golang的设计思想,但是你没法否定它在各种设计上简单和鲁棒。就跟map遍历一样,就是要加随机种子使它无序。我不搞golang开发,所谓的cultist也就呵呵了。既然你这么讨厌golang,干嘛还要用它研究它 【 在 Zelda 的大作中提到: 】 : 我真是服了您这种Golang maniac/cultist。逻辑上的无穷和实际的无限大是一回事吗?您按照的您的思路回答一下,为什么slice可以不用限定最大容量?你要无脑往Slice里装超过内存的数据?有些情况根本没法预估问题的规模,比如BFS,这个时候当然需要一个逻辑上“无限大”的queue。 : 换个问法问您,Python的queue.Queue、Java的BlockingQueue都是没意义的?这些设计都是为了让人撑爆内存的? : Golang大概是诞生于21世纪的语言中,技术品味最差的一个,还有一堆cultists无脑洗地,简直了……
zenghuaidong机器人#6 · 2019/5/16
问问自己,什么时候会用到无限大的队列来解决问题,有没有可能是自己的问题定义错了
lance6716机器人#7 · 2019/5/16
刚开始学go还不了解,原来buffered channel是这个意思……那实际上是需要一个不阻塞写入、动态扩容的channel吧。我这么菜也不知道底层怎么实现的,能不能检测到满了就重新申请两倍拷过去并且不触发通知等待者
Zelda机器人#8 · 2019/5/16
您问问自己,没有无限大的Queue怎么BFS。先DFS一次计算规模?那你不还是需要一个无限的stack? 最简单的场景,我给你一颗二叉树的根节点,树的规模未知,你来用channel层序遍历一下试试。 Golang用户都不学数据结构的嘛…… 【 在 zenghuaidong 的大作中提到: 】 : 问问自己,什么时候会用到无限大的队列来解决问题,有没有可能是自己的问题定义错了
Zelda机器人#9 · 2019/5/16
嗯嗯,标准库不算语言的一部分,您赢了。 您不是说无限大的队列没意义吗?您倒是说说没这玩意怎么BFS啊,让我也学习学习。 【 在 wanghaohebe 的大作中提到: 】 : Python的queue.Queue、Java的BlockingQueue都不是语言层面的东西吧?你要是觉得这种无限大的队列有必要你可以自己写了往golang的标准库里面提交啊?你觉得你比golang的设计者还牛逼?逻辑上的无穷和实际的无限大不是一回事,就是要在设计上就不让没水平的代码导致实际的无限大。通过通信共享内存,不是让你用通信来撑爆内存的。你可以不喜欢golang的设计思想,但是你没法否定它在各种设计上简单和鲁棒。就跟map遍历一样,就是要加随机种子使它无序。我不搞golang开发,所谓的cultist也就呵呵了。既然你这么讨厌golang,干嘛还要用它研究它 :