0

继我之前的问题 [here][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 
4

2 回答 2

1

编辑:经过编辑以反映您的修订和表格更改

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

如果我理解正确,您可能希望在设置局部变量(例如文件名)后进行分叉。这是一个简化的示例:

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
  }
}
于 2012-04-23T01:45:31.517 回答
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()是作为一种防御机制来防止错误实现的幼稚函数。

于 2012-04-23T03:36:38.687 回答