免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5920 | 回复: 18
打印 上一主题 下一主题

生产者,消费者的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-12 16:08 |只看该作者 |倒序浏览
本帖最后由 jlccwss 于 2010-08-12 16:56 编辑
  1. int insert_item(ITEM item)
  2. {
  3.         if(tail_>= size_)
  4.        {
  5.                 tail_ %= size_;
  6.         }
  7.         if((tail_ + 1)  != head_)
  8.         {
  9.                 //printf("The queue is full\n");
  10.                 item_buf_[tail_++] = item;
  11.                 return 0;
  12.         }
  13.         else
  14.                 return -1;
  15. }

  16. ITEM remove_item()
  17. {
  18.         if(head_>= size_)
  19.        {
  20.                 head_ %= size_;
  21.         }
  22.         if(head_ == tail_)
  23.         {
  24.                 //printf("The queue is epmty\n");
  25.                 return NULL;
  26.         }
  27.         else
  28.                 return  item_buf_[head_++];
  29. }
复制代码
insert_item
remove_item
主要看这两个方法的实现,
在insert的时候,如果((tail_ + 1)  != head_)就丢掉此次插入的数据
在remove的时候,如果(head_ == tail_)就返回NULL

请高人指点小弟下,没有用锁,这个会有什么问题。item_buf_这个空间是当数组队列来用的。

一会线程存,一个线程取

除了会丢失数据,还会有别的问题么?

论坛徽章:
0
2 [报告]
发表于 2010-08-12 16:38 |只看该作者
太长。又是C++的。我懒了。等其它高人

论坛徽章:
0
3 [报告]
发表于 2010-08-12 16:49 |只看该作者
本帖最后由 jlccwss 于 2010-08-12 16:51 编辑

回复 2# zhangsuozhu


    给你来个短的
  1. int insert_item(ITEM item)
  2. {
  3.         if(tail_>= size_)
  4.        {
  5.                 tail_ %= size_;
  6.         }
  7.         if((tail_ + 1)  != head_)
  8.         {
  9.                 //printf("The queue is full\n");
  10.                 item_buf_[tail_++] = item;
  11.                 return 0;
  12.         }
  13.         else
  14.                 return -1;

  15. }

  16. ITEM remove_item()
  17. {
  18.         if(head_>= size_)
  19.        {
  20.               head_ %= size_;
  21.         }

  22.         if(head_ == tail_)
  23.         {
  24.                 //printf("The queue is epmty\n");
  25.                 return NULL;
  26.         }
  27.         else
  28.                 return  item_buf_[head_++];
  29. }
复制代码
在insert的时候,如果((tail_ + 1)  != head_)就丢掉此次插入的数据
在remove的时候,如果(head_ == tail_)就返回NULL

指点小弟下,没有用锁,这个会有什么问题。item_buf_这个空间是当数组队列来用的。

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
4 [报告]
发表于 2010-08-12 16:50 |只看该作者
循环列表不加锁吗?

论坛徽章:
0
5 [报告]
发表于 2010-08-12 16:53 |只看该作者
回复 4# mirnshi


    就是这个问题,不加锁有没有什么问题。

生产:在队尾+1等于队头的情况下,我不存数据
消费:在队头==队尾的情况下,我不取数据

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
6 [报告]
发表于 2010-08-12 16:54 |只看该作者
回复  mirnshi


    就是这个问题,不加锁有没有什么问题。

生产:在队尾+1等于队头的情况下,我不 ...
jlccwss 发表于 2010-08-12 16:53


多线程下不可用。

论坛徽章:
0
7 [报告]
发表于 2010-08-12 16:55 |只看该作者
回复 6# mirnshi


    一个线程存,一个线程取,为什么不可用,哪里会有问题,能说一下么,谢谢

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
8 [报告]
发表于 2010-08-12 16:58 |只看该作者
回复  mirnshi


    一个线程存,一个线程取,为什么不可用,哪里会有问题,能说一下么,谢谢
jlccwss 发表于 2010-08-12 16:55


呵呵,这都属于操作系统课程里必考的。你的队列指针不会一致呀

论坛徽章:
0
9 [报告]
发表于 2010-08-12 17:17 |只看该作者
回复 8# mirnshi


    麻烦你了,能举个例子么?

我的目的很简单,只要存取不冲突就可以。
在头和尾之间,我留出了一个空位置

论坛徽章:
0
10 [报告]
发表于 2010-08-12 17:27 |只看该作者
本帖最后由 zhangsuozhu 于 2010-08-12 17:34 编辑

多线程序下,只有原子操作,不能被打断, 其它的都可能在执中过程中被别处的一个线程打断,而失去控制权。

如果不加锁,要保证在再次获得控制权恢复后,用到的变量和原来一样。
现代操作系统中,一般都提供了原子操作来实现一些同步操作,所谓原子操作,也就是一个独立而不可分割的操作。在单核环境中,一般的意义下原子操作中线程不会被切换,线程切换要么在原子操作之前,要么在原子操作完成之后。更广泛的意义下原子操作是指一系列必须整体完成的操作步骤,如果任何一步操作没有完成,那么所有完成的步骤都必须回滚,这样就可以保证要么所有操作步骤都未完成,要么所有操作步骤都被完成。

例如在单核系统里,单个的机器指令可以看成是原子操作(如果有编译器优化、乱序执行等情况除外);在多核系统中,单个的机器指令就不是原子操作,因为多核系统里是多指令流并行运行的,一个核在执行一个指令时,其他核同时执行的指令有可能操作同一块内存区域,从而出现数据竞争现象。多核系统中的原子操作通常使用内存栅障(memory barrier)来实现,即一个CPU核在执行原子操作时,其他CPU核必须停止对内存操作或者不对指定的内存进行操作,这样才能避免数据竞争问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP