2013-08-05 3 views
0

Мне было предложено разработать сторону потребителя (клиента) производителю (серверу), где производитель создает процессы, ждет, пока потребитель не будет читать разделяемую память и удаленные процессы, а затем передает управление производителю для уничтожения процессов и выключения блока разделяемой памяти.Interprocess Communication fork() - Timing wait() и/или sleep()

Я исследовал разницу между сном и ожиданием, и понимаю, что как только вызывается 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

Спасибо за ответ (и). Я не должен использовать трубы, а производитель и потребитель должны читать то, что находится в общей памяти, и в зависимости от установленного в памяти флага указателя выполняют свои различные задачи. Если вы хотите его увидеть, я могу приложить полный код производителя в моем ответе выше, поможет ли это? – viKK

+0

Должен признаться, что я не совсем уверен, что ваша цель здесь ... Обычно производитель/потребитель идет, как «Производитель производит, пока есть место, а потребитель потребляет, пока есть продукты» ... Знаете ли вы, как обрабатывать общие Память? –

+0

Спасибо за ответ, еще раз. Пример того, что мне нужно сделать, можно найти в разделе «Пример двух процессов, связанных через общую память: shm_server.c, shm_client.c» @ http://www.cs.cf.ac.uk/Dave/C/node27. html # SECTION002730000000000000000 – viKK

2

wait делают родитель заблокирован до любого ребенка конец .Вы можете использовать waitpid пусть родитель ждать конкретного ребенка.

Когда конец дочернего процесса, он установит сигнал SIG_CHILD.

2

pid равно нулю для дочернего процесса после вилки, поэтому вы находитесь в дочернем процессе при вызове функции srand.

Другой pid - это для дочернего процесса, который позволяет оригинальной нити дождаться окончания ребенка. Если вы хотите передать данные между процессами, используйте трубку. Вызов popen возвращает два дескриптора файла, один для записи, а другой - для чтения. Установите это перед вилкой, и два процесса могут обмениваться данными.