2012-11-14 69 views
1

我的代碼是在這裏: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 

的目標是服務生必須接受訂單,然後給他們做飯。服務員必須等待廚師完成所有披薩,送披薩,然後接受新的訂單。

我問P-V如何在我以前的文章here中工作。

我不認爲它與\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,然後去子進程(電磁爐),然後將控制權轉移回母公司,完成waiter_as_consumer,切換回到孩子。兩個等待切換回父(如我說我嘗試了所有可能的等待()組合...)。

+0

哪個等待操作可以阻止相應的進程? – millimoose

+0

另外,'wait()'做了什麼?如果它是POSIX函數,那麼它不應該是必須的,''P()'也許'V()'應該等待。 – millimoose

+0

,這是頭文件http://pastebin.com/4Jse4bRg和P,V在最後定義。 – User007

回答

2
  • 變化#define PERMS (0)(這是一個八進制文件模式掩碼!)
  • 通過的sizeof刪除所有wait();小號
  • 規模大小:if((shmid=shmget(1000,sizeof (int) * BUFSIZE,IPC_CREAT | PERMS)) < 0),和其他人(大小規模的擴大,模semsize/pagesize,但是反正使用合適的尺寸是個好習慣)

解決了這裏的問題。

整個想法是:你不需要需要等待;所述之一{生產者,消費者}將被阻塞,在P()某處:

從P():

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

除此之外:至少wait(&status)需要的參數。 (你可能會需要的其他等待功能之一,如wait3()或waitpid函數())

額外除了:

  • 共享對象的聲明之前,我會把「揮發」: volatile int *buff;
  • 的main()應該返回INT,沒有價值的回報是錯誤的(C99之前)
  • 大部分的指針操作很笨拙:order = buffer[i];相同order = *(buffer+i);,但更具可讀性。
+0

我在猜測教練提供了什麼。我的操作系統模塊在SysV IPC上也有一個毫無意義的包裝。 (這似乎是OS教師教授課程的一個問題,就好像他們期望學生必須在POSIX前的系統上工作一樣。) – millimoose

+0

它可以被看作是RTFM的練習。 – wildplasser

+0

更像是一種鍛鍊身體的鍛鍊。這個API被放棄的原因是有原因的,那是因爲它很煩人。如果你想讓學生使用RTFM,你不會給他們一個封裝函數的頭文件。正如你在答案中指出的那樣,實際上已經破裂了。 (至少我不會,我會將人們指向POSIX API的文檔,並使用這些調用來教授課程,而不是'P'和'V'。) – millimoose