2013-08-05 60 views
0

我被要求將消費者(客戶端)開發到生產者(服務器),生產者創建進程,等待消費者讀取共享內存和刪除的進程,然後將控制傳回給生產者以殺死進程並關閉共享內存塊。進程間通信fork() - 定時等待()和/或睡眠()

我研究了睡眠和等待之間的區別,並意識到只要fork()被調用,子進程就開始運行。

下面的代碼是在創建進程之後檢查它們是否是父進程。如果是,他們等待(0)。 *現在對於我的問題,我如何知道消費者中的代碼開始執行的位置,以及如何將其傳回? *

else if(pid > 0) 
       { 
        wait(0); 
       } 

下面可以看到生產者使用的主循環。

int noToCreate = atoi(argv[2]); // (user inputs on cmd line "./prod 20 10 5" - 20 size of shared mem, 10 process to be created, 5 processes to be deleted) 

while(*memSig != 2) 
    { 
     while(*memSig == 1) // set memsignature to sleep while.. 
     { 
      sleep(1); 
     } 

     for(B = 0; B < noToCreate; B++)  
     { 
      pid = fork(); 

      if(pid == -1) 
      { 
       perror("Error forking"); 
       exit(1); 
      } 
      else if(pid > 0) 
      { 
       wait(0); 
      } 
      else 
      { 
       srand(getpid()); 

       while(x == 0) 
       { 
        if(*randNum == 101) 
        { 
         *randNum = rand() % (100 - 

1) + 1; 
         *pidNum = getpid(); 

         printf("priority: %d 

Process ID: %d \n", *randNum, *pidNum); 

         x = 1; 
        } 
        else 
        { 
         *randNum++; 
         *pidNum++; 
        } 
       } 
       exit(0); 
      } 
     } /* Closes main for loop */ 

     if(*memSig == 0) 
     { 
      *memSig = 1; 
     } 
    } /* Closes main while loop */ 

多謝你們:)

回答

1

wait使家長等待任何孩子纔去上(最好使用waitpid等待某個孩子)終止,而sleep放過程睡覺恢復它,只要時間過去了,因爲參數結束了。
這兩個調用將使過程
而且它是不是表示孩子會立即跑步,這是不確定的行爲!

如果您想要在生產者和消費者之間傳遞數據,請使用管道或* NIX套接字,或者如果單個整數足夠,則使用來自子項的返回值exit

請參閱man wait,您可以通過宏WEXITSTATUS獲取子項的返回值。阻塞,直到所有子

#include <sys/wait.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 

int 
main(int argc, char *argv[]) 
{ 
    pid_t cpid, w; 
    int status; 

    cpid = fork(); 
    if (cpid == -1) { 
     perror("fork"); 
     exit(EXIT_FAILURE); 
    } 

    if (cpid == 0) {   /* Code executed by child */ 
     printf("Child PID is %ld\n", (long) getpid()); 
     if (argc == 1) 
      pause();     /* Wait for signals */ 
     _exit(atoi(argv[1])); 

    } else {     /* Code executed by parent */ 
     do { 
      w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); 
      if (w == -1) { 
       perror("waitpid"); 
       exit(EXIT_FAILURE); 
      } 

      if (WIFEXITED(status)) { 
       printf("exited, status=%d\n", WEXITSTATUS(status)); 
      } else if (WIFSIGNALED(status)) { 
       printf("killed by signal %d\n", WTERMSIG(status)); 
      } else if (WIFSTOPPED(status)) { 
       printf("stopped by signal %d\n", WSTOPSIG(status)); 
      } else if (WIFCONTINUED(status)) { 
       printf("continued\n"); 
      } 
     } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
     exit(EXIT_SUCCESS); 
    } 
} 
+0

感謝您的回覆。 我不需要使用管道,相反,生產者和消費者應該閱讀共享內存中的內容,並根據內存中設置的指針標誌執行各種任務。 如果你希望看到它,我可以在我的上面的答案中附上完整的producer.c代碼,會有幫助嗎? – viKK

+0

我必須承認我不太清楚你的目標是在這裏......通常,生產者/消費者喜歡「生產者生產,而有空間和消費者消費,而有產品」... 你知道如何處理共享記憶? –

+0

再次感謝您的回覆。 @ http://www.cs.cf.ac.uk/Dave/C/node27:什麼我需要一個例子可以在「shm_server.c,shm_client.c實施例兩個進程通過共享存儲器comunicating」中找到。 html#SECTION002730000000000000000 – viKK

2

wait化妝父結束。你可以使用waitpid讓家長等待特定子。

當子進程結束時,它會設置一個信號SIG_CHILD

2

在fork之後,子進程的pid爲零,因此您在調用srand函數時處於子進程中。

另一個PID是允許他的原始線程等待孩子完成的子進程。如果您希望在流程之間傳遞數據,請考慮使用管道。 popen調用返回兩個文件描述符,一個寫入結束,另一個寫入讀取結束。在fork和兩個進程可以通信之前進行設置。