为什么我的生产者 - 消费者阻止?

时间:2012-11-14 20:51:48

标签: c algorithm unix semaphore producer-consumer

我的代码在这里:http://pastebin.com/Fi3h0E0P

这是输出

0
Should we take order today (y or n): y
Enter order number: 100
More customers (y or n): n

Stop serving customers right now. Passing orders to cooker:
There are total of 1 order(s)
1
Roger, waiter. I am processing order #100

目标是服务员必须接受命令,然后将它们交给厨师。服务员必须等待厨师完成所有披萨,送上披萨,然后接受新订单。

我在上一篇文章here中询问了P-V的工作原理。

我不认为它与\n消费有什么关系?我尝试了wait()的各种组合,但都没有效果。

我在哪里弄错了?

主要部分在这里:

//Producer process
 if(pid > 0)
 {
    while(1)
    {
      printf("0");
      P(emptyShelf); // waiter as P finds no items on shelf;
      P(mutex); // has permission to use the shelf
      waiter_as_producer();
      V(mutex); // cooker now can use the shelf
      V(orderOnShelf); // cooker now can pickup orders

      wait();
      printf("2");
      P(pizzaOnShelf);
      P(mutex);
      waiter_as_consumer();
      V(mutex);
      V(emptyShelf);
      printf("3 ");
    }
 }
    if(pid == 0)
    {
     while(1)
    {
     printf("1");
     P(orderOnShelf); // make sure there is an order on shelf
     P(mutex); //permission to work
     cooker_as_consumer(); // take order and put pizza on shelf
     printf("return from cooker");
     V(mutex); //release permission
     printf("just released perm");
     V(pizzaOnShelf); // pizza is now on shelf
     printf("after");
     wait();
     printf("4");

    }
  }

所以我想这是执行路径: 输入waiter_as_producer,然后转到子进程(cooker),然后将控件转回父级,完成waiter_as_consumer,切换回子级。两个等待切换回父级(就像我说我尝试了所有可能的wait()组合......)。

1 个答案:

答案 0 :(得分:2)

  • 更改为#define PERMS (0)八进制文件模式掩码!)
  • 删除所有wait(); s
  • 尺寸大小由sizeof:if((shmid=shmget(1000,sizeof (int) * BUFSIZE,IPC_CREAT | PERMS)) < 0)和其他(尺寸按模块semsize / pagesize放大,但无论如何使用正确尺寸都是一个好习惯)

解决了这个问题。

整个想法是:你不需要等待;其中一个{producer,consumer}将被阻塞在P()的某个地方:

来自P():

sb.sem_flg = 0; /* blocking call */
    if (semop(sid, &sb, 1) == -1)
        perror("semop");

此外:wait(&status)至少需要一个参数。 (你可能需要其他一个等待函数,比如wait3()或waitpid())

额外的:

  • 我会在共享对象的声明之前放置“volatile”:volatile int *buff;
  • main()应该返回int,返回没有值是错误的(在c99之前)
  • 大多数指针操作都很笨拙:order = buffer[i];order = *(buffer+i);相同,但更具可读性。