免费注册 查看新帖 |

Chinaunix

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

在内核中实现生产者消费者问题时的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-31 22:20 |只看该作者 |倒序浏览
本帖最后由 ipiszhang 于 2010-05-31 22:22 编辑

在内核中实现了一个最简单的生产者消费者模型 没有使用信号量 只用数组下标来控制同步问题 下面是代码
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>

  4. #include <linux/kthread.h>
  5. #include <linux/wait.h>
  6. #include <linux/time.h>
  7. #include <linux/delay.h>
  8. #include <asm/param.h>

  9. #define        MY_MODULE_VERSION        "v0.1"
  10. #define        MODULE_NAME                "produdcer_consumer"

  11. #define        SECOND                0.00000001
  12. #define        BUFF_LEN        10

  13. int buffer[BUFF_LEN] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 0};

  14. int front = 0;
  15. int back = BUFF_LEN - 1;
  16. int goods = 20;

  17. static struct task_struct *producer_thread = NULL;
  18. static struct task_struct *consumer_thread = NULL;
  19. DECLARE_WAIT_QUEUE_HEAD(sleep_queue);

  20. unsigned long timeout = 1;

  21. static int producer(void *mode) {
  22.         int result = 0;
  23.         while(!kthread_should_stop()) {
  24.                 // printk("producer\n");
  25.                 if (back >= front && back - front < BUFF_LEN) {
  26.                         buffer[back % BUFF_LEN] = goods;
  27.                         back++;
  28.                         goods++;
  29.                         printk("producer: put goods [%d] to %d\n", goods - 1, (back - 1) % BUFF_LEN);
  30.                 } else {
  31.                         printk("producer: no space, sleeping\n");
  32.                         wait_event_interruptible_timeout(sleep_queue, (back >= front && back - front < BUFF_LEN), timeout);
  33.                 }
  34.         }
  35.         return result;
  36. }

  37. static int consumer(void *mode) {
  38.         int result = 0;
  39.         while(!kthread_should_stop()) {
  40.                 // printk("consumer\n");
  41.                 if (back > front) {
  42.                         printk("consumer: get goods [%d] from %d\n", buffer[front % BUFF_LEN], front % BUFF_LEN);
  43.                         front++;
  44.                 } else {
  45.                         printk("consumer: no goods, sleeping\n");
  46.                         wait_event_interruptible_timeout(sleep_queue, (back > front), timeout * 10);
  47.                 }
  48.         }
  49.         return result;
  50. }

  51. static int __init producer_consumer_init(void) {
  52.         int result = 0;
  53.         
  54.         producer_thread = kthread_run(producer, NULL, "producer");
  55.         if (!producer_thread) {
  56.                 result = -1;
  57.                 goto exit;
  58.         }

  59.         consumer_thread = kthread_run(consumer, NULL, "consumer");
  60.         if (!consumer_thread) {
  61.                 result = -1;
  62.                 goto exit;
  63.         }
  64.         
  65.         printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MY_MODULE_VERSION);
  66. exit:
  67.         return result;
  68. }

  69. static void __exit producer_consumer_exit(void) {
  70.         if (producer_thread)
  71.                 kthread_stop(producer_thread);
  72.                
  73.         if (consumer_thread)
  74.                 kthread_stop(consumer_thread);
  75.         
  76.         printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MY_MODULE_VERSION);
  77. }

  78. module_init(producer_consumer_init);
  79. module_exit(producer_consumer_exit);

  80. MODULE_LICENSE("GPL");
复制代码
首先启动生产者线程 接着启动消费者线程 缓冲区长度为10 开始时缓冲区里有前9个元素 生产者从第10个位置开始放置产品

发现一个问题 根据判断条件
  1. if (back >= front && back - front < BUFF_LEN)
复制代码
只要有空间 生产者就生产并放进缓冲区
  1. if (back > front)
复制代码
只要有产品 消费者就从缓冲区取出
所以执行结果应该是生产者消费者一次次交替运行
但是现在运行后发现 生产者生产10次填满缓冲区后消费者才消费 消费者将缓冲区的10个数据都取走后生产者才继续生产 而不是二者一次次交替运行

请问各位 这是为什么呢?

论坛徽章:
0
2 [报告]
发表于 2010-06-01 16:02 |只看该作者
我怀疑是由于同步的问题导致的。

把front、back、good改为atomic_t试试。

论坛徽章:
0
3 [报告]
发表于 2010-06-01 19:57 |只看该作者
我怀疑是由于同步的问题导致的。

把front、back、good改为atomic_t试试。
ShadowStar 发表于 2010-06-01 16:02



    他这个代码看上去逻辑好像没问题,确实有点奇怪。如果是atomic的原因,为什么正好是十次才替换?

论坛徽章:
0
4 [报告]
发表于 2010-06-02 09:57 |只看该作者
这种模型在实际中有何用处?有没具体的例子
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP