使用Fork()计算多个文件的行数,其中每个子项独立运行

时间:2012-04-23 01:24:13

标签: c linux fork

按照我之前的问题[这里] [1],我现在想要计算多个文件的行数,我想要放置进程的每个文件的位置,这个问题的子进程,将运行该方法calculateLines为自己的文件,并找到其文件的行数。

我写了fork()作为系统调用(称为my_fork()),这里是代码:

 int main(int argc, char *argv[])
 {

     typedef struct fileChild {
       pid_t processID;
       char *fileName;
       int processFileLines;
     }  child;


     child children[argc];        // array of children

     int n = 0;   // using this to tell how much lines in a single file
     int i = 0;   // using this to iterate the number of files
     char dig;    // using this to convert into char the number of lines

     while (i < argc )
     {
         children[i].processID = my_fork();  // create process 'i' for file 'i'
         children[i].fileName = argv[i];
         children[i].processFileLines = calculateLines(children[i].fileName);
     }

     ....
     ....

     return 0;
 }

我的问题:这是子进程如何检查其文件的行数(文件i)? 我无法看到这个(分叉)如何改进我的代码...请放轻松我,这是我第一次使用流程。

最终版本:

#include <stdio.h>

 typedef unsigned int size_t;
 typedef signed ssize_t;

 int main(int argc, char *argv[])
 {



     char myArray[15];


     int n = 0;
     int i = 0;
     pid_t pid;


     for (i = 1; i < argc; i++)
     {

         if ((pid = my_fork()) == 0)

         {
             n = calculateLines(argv[i]);
             sprintf (myArray, "\nfile%d: %d \n", i,n);
             my_write(1,myArray,15);

         }
        else if (pid < 0)
            break;

     }

     return 0;
 }

终端测试:

a@ubuntu:~/Desktop$ ./ProjOsFInal somefile.txt about.html epl-v10.html
a@ubuntu:~/Desktop$ 
file2: 300 

file1: 133 

file3: 327 

file2: 300 

file3: 327 

file3: 327 

file3: 327 

2 个答案:

答案 0 :(得分:1)

编辑:编辑它以反映您的修订和表单更改

fork()返回它创建的子进程的ID,如果是创建的子进程,则返回0。因此,如果您可以使用它来区分您是否需要更多分叉的父母,或者应该忙于计算行数的孩子。

如果我理解正确,你需要在设置诸如fileName之类的局部变量之后进行分叉。这是一个简化的例子:

const char *local_filename;
pid_t f;
int i = 0;
while (i < argc) {
  i++;
  local_filename = argv[i];
  f =  my_fork();
  if (f == 0) { // fork() returns 0 if we are a child, so we want to be a child prcess here
    calculate stuff;
    ...
    break; // Since we're a child we don't want to go on and spawn more, so we exit the loop and are done
  }
}

答案 1 :(得分:1)

我认为你可以稍微简化代码。您遇到的一个问题是您当前正在处理argv[0],这是程序的名称而不是其任何参数。

int main(int argc, char **argv)
{
    pid_t kids[argc];   // VLA
    int n_kids = 0;

    for (int i = 1; i < argc; i++)
    {
        pid_t pid;
        if ((pid = my_fork()) == 0)
        {
            be_childish(argv[i]);
            /*NOTREACHED*/
            exit(EXIT_FAILURE);
        }
        else if (pid < 0)
            break;
        else
            kids[n_kids++] = pid;
    }
    int status;
    while ((pid = waitpid(-1, &status, 0)) > 0)
        n_kids = note_death_of_child(pid, status, n_kids, kids);
    return(0);
}

note_death_of_child()函数只是在列表中找到该条目。实际上,你真的不需要这里的孩子名单,但你可以注意到每个孩子退出,以及退出状态是什么。

be_childish()函数被赋予文件名。它打开文件,读取它,关闭它,写入需要写入的内容,然后退出。在exit()函数的循环中对main()的调用是作为防止错误实现的幼稚函数的防御机制。