存在不加锁的生产者和消费者队列么?

TheNewIpad 2014-06-03 04:41:02
现在需求里面,锁太拉低性能了。 所以想看看有木有不需要锁的生产者和消费者队列。

在网上搜索,发现都用的ringbuffer那样的循环队列。 可是怎么看怎么都不安全啊。
...全文
1956 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
iegad 2016-05-24
  • 打赏
  • 举报
回复
今天去腾讯面试, 笔试题最后一题, 就是实现不加锁的 生产者-消费者 模型, (单个消费者和生产者的环境下). 那些说什么在如今天这个硬件满天飞的时代, 性能什么什么的, 别在这里误导他人, 自己不进取, 不要害别人! 不说多的, 奔4CPU的年代, 你的数据量有多大? 现在你看看是的, 硬件有了飞跃, 但是有没有想过数据量有多大? T都以经不能满足需求了, 所以性能方面还是要重视的! 今天技术1面的最后一题就是在一个40多亿的数据里面进行去重处理!, 你不要告诉我说你的解决方案是把这个问题放在天河二号上去执行!
JamesWatson 2014-07-04
  • 打赏
  • 举报
回复
go语言中有一种思路,用管道。
e3internet 2014-06-24
  • 打赏
  • 举报
回复
不存在你想的这样模式,想要保持同步就必须加锁,只是看锁的使用频率
还差得远呢 2014-06-17
  • 打赏
  • 举报
回复
这篇帖子对我的帮助很大啊,学到了很多
yangyunzhao 2014-06-17
  • 打赏
  • 举报
回复
目前来说锁应该不是问题,估计是设计有问题。 对了,如果要不加锁的队列的话,可以参考boost::lockfree,里面有好几种特定条件下的无锁队列
lucifer886 2014-06-17
  • 打赏
  • 举报
回复
引用 楼主 TheNewIpad 的回复:
现在需求里面,锁太拉低性能了。 所以想看看有木有不需要锁的生产者和消费者队列。 在网上搜索,发现都用的ringbuffer那样的循环队列。 可是怎么看怎么都不安全啊。
我记得看到过一篇博客有专门分析过加锁的耗时开销,目前主流的CPU一半只要个9ns……肯定不是锁的问题
bobo_包子 2014-06-14
  • 打赏
  • 举报
回复
涉及共享内存,就没有不加锁的。除非你是单线程。
碼上道 2014-06-13
  • 打赏
  • 举报
回复
引用 15 楼 TheNewIpad 的回复:
经过仔细测量, 发现不是锁问题,锁耗时大约是0.0005ms左右。 这样的锁,在生产者和消费者的队列中,能满足我最多10W/秒的同步。 而我的同步次数只是 3W/秒。 问题出在其他内核IO上了。 谢谢各位。 不过尽管如此,还是感觉,这样的锁太浪费性能了。 不知道有没有更好的设计。
你用什么形式的锁? 无论什么锁,关键要统计一下锁冲突的概率高不高,如果冲突概率高,肯定要重新设计队列的。 当然用锁不表示一定效率低。
TheNewIpad 2014-06-13
  • 打赏
  • 举报
回复
经过仔细测量, 发现不是锁问题,锁耗时大约是0.0005ms左右。 这样的锁,在生产者和消费者的队列中,能满足我最多10W/秒的同步。 而我的同步次数只是 3W/秒。 问题出在其他内核IO上了。 谢谢各位。 不过尽管如此,还是感觉,这样的锁太浪费性能了。 不知道有没有更好的设计。
horris 2014-06-05
  • 打赏
  • 举报
回复
什么关键段、互斥量、事件、信号量,都是锁的不同形式,复杂程度不同,系统开销不同,包括InterlockedXxxx,都一样,适应场合也不尽相同,用不好都会造成执行效率下降甚至死锁。数据库也有锁,我亲身体验过,用不好效率相差一个数量级。 不要心存侥幸,不加锁的话,多线程的并发冲突很难发现和调试。
赵4老师 2014-06-04
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
水平不流 2014-06-04
  • 打赏
  • 举报
回复
不懂,坐等大神解答,我觉得不存在。不知道如果是用数据库去帮忙做这些互斥性方面的工作,是不是效率就更低了?
regainworld 2014-06-04
  • 打赏
  • 举报
回复
看过一个解决方案,使用链表的,用于高速数据处理:
就想叫yoko 2014-06-04
  • 打赏
  • 举报
回复
boost::lockfree::queue 反正我是没用过 你觉得锁太拉低性能那基本上是设计有问题
TheNewIpad 2014-06-04
  • 打赏
  • 举报
回复
引用 7 楼 my3439955 的回复:
对于环形缓冲区: 1、单个生产者,单个消费者共两个线程的,可以不加锁。例如环形缓冲区的大小是1000,两线程各保有一个递增变量x,每次操作x%1000位置的数据即可。也就是说,生产者始终知道自己该往哪放新产品,消费者始终知道自己该在哪取新产品。 需要注意的是,消费者不积极的时候,生产者可能会把缓冲区填满,这个是大问题。不加锁就要求缓冲区足够大。 2、多个生产者多个线程,多个消费者多个线程的,可以利用Interlocking来做锁,和一般的内核锁相比效率是大大提高了的,可以忽略不计。仍然可以用上边的思路。
在消费者积极的情况下, 如果不存在追赶。 的确不需要锁。 但是当存在追赶,例如在产能持续过剩的情况下 或者 消费者根本不消费。 生产者持续生产。 此时肯定存在生产者覆盖消费者即将要取数据的可能。 即生产者和消费者同时操作同一份内存。 不加锁, 还是不行啊。 除非ringbuffer不存在覆盖机制。
赵4老师 2014-06-04
  • 打赏
  • 举报
回复
《Windows核心编程》 Synchronization Functions The following functions are used in synchronization. CancelWaitableTimer CreateEvent CreateMutex CreateSemaphore CreateWaitableTimer DeleteCriticalSection EnterCriticalSection GetOverlappedResult InitializeCriticalSection InitializeCriticalSectionAndSpinCount InterlockedCompareExchange InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedIncrement LeaveCriticalSection MsgWaitForMultipleObjects MsgWaitForMultipleObjectsEx OpenEvent OpenMutex OpenSemaphore OpenWaitableTimer PulseEvent QueueUserAPC ReleaseMutex ReleaseSemaphore ResetEvent SetCriticalSectionSpinCount SetEvent SetWaitableTimer SignalObjectAndWait TimerAPCProc TryEnterCriticalSection WaitForMultipleObjects WaitForMultipleObjectsEx WaitForSingleObject WaitForSingleObjectEx
还差得远呢 2014-06-04
  • 打赏
  • 举报
回复
从逻辑上说,加锁是应该的,这样生产者和消费者可以有条不紊的使用公共的数据区。不过还可以使用信号量来进行控制,感觉比锁用着方便一点,楼主可以关注一下信号量。
  • 打赏
  • 举报
回复
对于环形缓冲区: 1、单个生产者,单个消费者共两个线程的,可以不加锁。例如环形缓冲区的大小是1000,两线程各保有一个递增变量x,每次操作x%1000位置的数据即可。也就是说,生产者始终知道自己该往哪放新产品,消费者始终知道自己该在哪取新产品。 需要注意的是,消费者不积极的时候,生产者可能会把缓冲区填满,这个是大问题。不加锁就要求缓冲区足够大。 2、多个生产者多个线程,多个消费者多个线程的,可以利用Interlocking来做锁,和一般的内核锁相比效率是大大提高了的,可以忽略不计。仍然可以用上边的思路。
horris 2014-06-03
  • 打赏
  • 举报
回复
ring buffer如果是单线程的应用,当然不需要加锁了,这时ring buffer主要解决的是空间分配问题。但如果用在多线程里,必须加锁。要提高效率必须仔细设计,比如说你多搞几个buffer,生产者分段写入,消费者分段读出,每个buffer设计一个锁,这样生产者消费者同时等待同一个锁的几率就低了。
horris 2014-06-03
  • 打赏
  • 举报
回复
先要明白为什么要加锁,推理出必须加锁,至于效率问题,数据结构、算法与锁的配合设计不合理
加载更多回复(3)

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧