2013-08-05 59 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和两个进程可以通信之前进行设置。