User007
User007

Reputation: 1559

Why is my producer-consumer blocking?

My code is here: http://pastebin.com/Fi3h0E0P

Here is the output

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

The goal is waiter must take orders and then give them to the cook. The waiter has to wait cook finishes all pizza, deliver the pizza, and then take new orders.

I asked how P-V work in my previous post here.

I don't think it has anything to do with \n consuming? I tried all kinds of combination of wait(), but none work.

Where did I make a mistake?

The main part is here:

//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");

    }
  }

So I imagine this is the execution path: enter waiter_as_producer, then go to child process (cooker), then transfer the control back to parent, finish waiter_as_consumer, switch back to child. The two waits switch back to parent (like I said I tried all possible wait() combination...).

Upvotes: 1

Views: 237

Answers (1)

wildplasser
wildplasser

Reputation: 44250

  • change to #define PERMS (0) (it is NOT an octal file mode mask!)
  • remove all the wait();s
  • scale size by sizeof: if((shmid=shmget(1000,sizeof (int) * BUFSIZE,IPC_CREAT | PERMS)) < 0) , and others (the size is scaled up modulo semsize/pagesize, but it is a good habit to use the right size anyway)

fixed the problem here.

The whole idea is: you don't need to wait; one of the {producer,consumer} will be blocked on a P() somewhere:

from P():

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

And besides: wait(&status) needs at least an argument. (and you would probably need one of the other wait functions, such as wait3() or waitpid() )

Extra besides:

  • I would put "volatile" before the declarations of the shared objects: volatile int *buff;
  • main() should return int, returns without a value are wrong (before c99)
  • most of the pointer operations are clumsy: order = buffer[i]; is the same as order = *(buffer+i);, but more readable.

Upvotes: 2

Related Questions