C 使用Fork()计算多个文件的行数,其中每个子文件单独运行
在我前面的问题[here][1]之后,我现在想计算多个文件的行数,在每个文件中我想放置一个进程,一个子进程,它将为自己的文件运行方法C 使用Fork()计算多个文件的行数,其中每个子文件单独运行,c,linux,fork,C,Linux,Fork,在我前面的问题[here][1]之后,我现在想计算多个文件的行数,在每个文件中我想放置一个进程,一个子进程,它将为自己的文件运行方法calculateLines,并找到文件的行数 我编写了fork()作为系统调用(称为myfork()),下面是代码: int main(int argc, char *argv[]) { typedef struct fileChild { pid_t processID; char *fileName;
calculateLines
,并找到文件的行数
我编写了fork()
作为系统调用(称为myfork()
),下面是代码:
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;
}
终端测试:
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
编辑:编辑此项以反映您的修订和表单更改 fork()返回它创建的子进程的进程ID,如果它是创建的子进程,则返回0。所以如果你能用这个来区分你是父母,需要更多的叉子,还是孩子,应该忙着数线 如果我理解正确的话,您可能希望在设置本地变量(如fileName)后使用fork。下面是一个简化的示例:
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
}
}
const char*本地文件名;
pid_t f;
int i=0;
而(i
我想你可以把代码简化一点。您遇到的一个问题是当前正在处理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);
}
int main(int argc,char**argv)
{
pid_t kids[argc];//VLA
int n_kids=0;
对于(int i=1;i0)
n_kids=注意_child的死亡(pid、状态、n_kids、kids);
返回(0);
}
函数的note\u death\u of \u child()
只在列表中查找条目。实际上,这里确实不需要子项列表,但是您可以注意每个子项退出时的状态,以及它的退出状态
be_childish()
函数被赋予文件名。它打开文件、读取文件、关闭文件、写入需要写入的内容,然后退出。调用main()
函数循环中的exit()
是一种防御机制,可以防止错误实现的幼稚函数。我想为每个进程分叉,这意味着分叉的唯一原因是计算另一个文件的行数。顺便说一句,我用“if(f==0)break;”将您丢失,为什么要中断?这意味着我将停止计数,其中有更多的文件要计数…fork()作为子进程时返回0。只有父进程应继续繁殖,父进程将返回0。子进程应该退出它所处的循环并开始计数,这就是为什么当我们收到通知我们是一个孩子时我们会中断的原因对不起,我的意思是父进程将获得0以外的返回值。我已经编辑了我的帖子,你能解释一下为什么除了“file1:2”行之外,我还获得Gibrish吗?非常感谢。最初看起来,在循环中的分叉之前,并没有增加i。在for循环中,它会在末尾正确地增加它:因此这是在生成正确的进程,它只是做了太多次而已。增加i应该是循环中的第一件事。我将更新我的答案以反映这一点。另外,如果你这样做,就没有必要使用(如果pid<0)好的,谢谢,你能看看我编辑的帖子吗?代码仍然有问题。出于某种原因,我得到了一些Gibrish。有两个问题:(1)您的新代码没有等到子进程完成后再尝试进行后处理,(2)您的子进程修改了自己的局部变量,但不能影响父进程的变量。您将需要一些其他机制将信息从子进程返回到父进程;管道和共享内存是两种可能性。我还没有“学习”管道,所以我不能使用它。共享内存是什么意思?如果您没有学习共享内存或管道,那么您对IPC(进程间通信)的选择非常有限,那么您需要停止让父进程尝试复制子进程所做的打印。完成后,子进程不会退出,因此,第一个子代返回并运行下一个迭代(以及父代),依此类推。你没有注意到我的大纲代码;注意,您应该重置i=1代码>而不是i=0代码>在最终循环之前。您可以使用for
循环,而不是while
循环。还有inti=0代码>位于顶部,紧接着是i=1代码>,这有点浪费(尽管编译器可能会为您优化)。
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);
}