2017-02-19 35 views
-1

我是c编程的新手,我遇到了这个实现问题。情况是我需要使用fork()创建4个子进程以循环方式打印命令行参数,即如果输入是./abc.c RR GG EE WW BB CC DD AA,子进程1应该存储和打印RR BB,子进程2应该存储和打印GG CC以及等等。最终的输出应该是这样的。以循环方式打印和存储命令行参数

Child 1, pid 23460: S5 HT DK S4 H7 S6 S8 D2 H3 H2 DT DA S9 
Child 2, pid 23461: C7 HA D6 S7 SQ HK H6 H4 C3 CK S2 C9 SJ 

3和4子进程有类似的输出。

问题是商店的一部分。我们如何正确存储这些参数并使用printf或其他方法来产生上述输出?一个子进程打印一行。我找不出解决方案。

存储要求是存储Child 1元素是一个数组。 S5 HT DK S4 H7 S6 S8 D2 H3 H2 DT DA S9,将子元素2存储在一个数组中。 C7 HA D6 S7 SQ HK H6 H4 C3 CK S2 C9 SJ等。

这是我在这一刻得到的。

#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 

void childFunction(char *argv[], int identify){ 
    int i; 
    for (i=1;i<sizeof(argv);i+=4){ 
     switch (identify){ 
     case 0: 
      printf("Child : %d %s\n", identify+1, argv[i]); 
      break; 
     case 1: 
      printf("Child : %d %s\n", identify+1, argv[i+1]); 
      break; 
     case 2: 
      printf("Child : %d %s\n", identify+1, argv[i+2]); 
      break; 
     case 3: 
      printf("Child : %d %s\n", identify+1, argv[i+3]); 
      break; 
     } 
    } 
    // do stuff 
} 

int main(int argc, char *argv[]){ 
    int childLimit = 4; // number of children wanted 
    int childrenPids[childLimit]; // array to store children's PIDs if needed 
    int currentPid, i; 

    for(i=0; i<childLimit; i++){ 
     switch(currentPid = fork()){ 
      case 0: 
       // in the child 
       childFunction(argv, i); 
       // exit the child normally and prevent the child 
       // from iterating again 
       return 0; 
      case -1: 
       printf("Error when forking\n"); 
       break; 
      default: 
       // in the father 
       childrenPids[i] = currentPid; // store current child pid 
       break; 
     } 

    } 

    printf("Father : %d childs created\n", i); 

    // do stuff in the father 

    //wait for all child created to die 
    waitpid(-1, NULL, 0); 
} 

更新要求: 我需要进一步明确的要求,这是我需要打印保持每个子进程的部件元件在阵列用新升序排序要求。

for(i = childnum; i < argc; i += 4) 
{ 
    for(j = 0; j < argc; j++) 
    { 
     a[j] = argv[i]; 
     printf("%s ", a[j]) ; 
     break; 
    } 
} 

它产生下面的输出:

./a.out ff ee gg tt hh oo ee pp 
Child : 1, pid 762 : ff hh 
Child : 3, pid 764 : gg ee 
Child : 2, pid 763 : ee oo 
Father : 4 childs created 
Child : 4, pid 765 : tt pp 

输出很好看,但如何将它们存储在独立阵列和

代码根据第一个答案修改执行一些排序,即子1元素的升序?

+1

如果您的示例输出都是完整的(即,所有四个进程)并且与先前对示例输入的描述相匹配,那么这将不那么令人困惑。 – Clifford

+0

“商店”是什么意思?存储在哪里,并为了什么目的? – Clifford

回答

1

childFunction()如果迭代从identify + 1开始,那么迭代指数,可直接用于选择参数,而不需要一个开关,从而:

void childFunction(char *argv[], int argc, int identify) 
{ 
    int childnum = identify + 1 ; 

    printf("Child : %d, pid %d : ", childnum, getpid()); 
    for(int i = childnum; i < argc; i += 4) 
    { 
     printf("%s ", argv[i]) ; 
    } 
    printf("\n") ; 
} 

注意需要传递argcchiledFunction(); sizeof(argv)不是参数个数的计数 - 它是char**指针的大小;在main()应将呼叫从而改变:

 childFunction(argv, argc, i); 

另一个建议的变化是输出的父亲文本waitpid()

//wait for all child created to die 
    waitpid(-1, NULL, 0); 

    printf("Father : %d children created\n", i); 

否则其产量可能出现在中间孩子的过程。

建议的更改产生以下(在我的测试):

sh-4.2$ main 11 22 33 44 55 66 77 88                                                
Child : 1, pid 156 : 11 55                                                  
Child : 3, pid 158 : 33 77                                                  
Child : 2, pid 157 : 22 66                                                  
Child : 4, pid 159 : 44 88                                                  
Father : 4 children created                                                   

注意孩子的执行顺序是不确定的。在上面的例子中,顺序是1,3,2,4,但在其他测试中是1,2,3,4 - YMMV。

+0

还有一个问题。如果我想要将11 55存储在数组中,33 77在其他数组中,22 66在第三个数组中,44 88在第四个数组中。那我该怎么办? –

+0

@SamAnnie:如果这是对你的“店铺”要求的澄清,那么应该在问题中澄清*而不是作为评论发布。如果它是一个单独的问题(它确实应该在任何情况下),然后发布一个单独的问题。评论既不是问题或答案。然而,相当明显的解决方案是维护第二个计数器(比如'j'),该计数器在循环中递增1而不是4,然后分配'child_argv [j] = argv [i];'。如果你要更新你的问题,所以它包括这个要求,那么我可以合法地将它添加到这个答案。 – Clifford

+0

该问题已根据您的答案更新。请提供有关此问题的最新答案。 –