【发布时间】:2016-01-21 17:13:35
【问题描述】:
我在将 fseek() 与 fork() 结合使用时遇到了问题(实际上是使用 XUbuntu 15.10)。
我必须编写一个程序,从文件(“file1”)中读取一系列数字(在不同的行中),并报告与特定字符串匹配的行数,作为参数传递。
我称为“nf”的程序必须按以下方式调用(./nf number_of_processes file1 match_string)。
程序应创建 number_of_processes 个子进程(使用 fork()),每个子进程应处理文件的单个部分(即,如果 number_of_processes 为 5 且文件有 15 行,则每个子进程应处理 15/5=3 行文件)。
然后子进程应将结果报告给父亲,父亲将打印在文件中找到的出现次数。
现在,问题是:我使用 fseek 编写了程序(每个子进程在文件中找到其正确位置并开始分析它的单个部分的长度),但有时它似乎工作,而其他一些它打印不正确的结果,就像它以不正确的方式读取文件(多次读取或读取垃圾而不是数字字符串)......
你知道为什么会这样吗?
提前非常感谢。
文件如下:
文件1:
1224332
1224332
4363666
4363666
1224332
5445774
2145515
1224332
2145515
1111111
2145515
9789899
2344444
6520031
4363666
nf.c:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define NBYTES 8
int FileLenght(FILE *fp) {
int cnt=0;
char c;
while((c=getc(fp))!=EOF) {
if(c=='\n') {
cnt++;
}
}
rewind(fp);
return cnt;
}
int main (int argc, char *argv[]) {
int num,vlen=0,i,j=0,cnt=0;
pid_t *pid;
int status,sum=0;
FILE *fp;
char string[NBYTES+1];
if(argc!=4) {
printf("Error using program.\n");
exit(EXIT_FAILURE);
}
num=atoi(argv[1]);
fp=fopen(argv[2],"r+");
if(!fp) {
fprintf(stderr,"Error opening file.\n");
exit(EXIT_FAILURE);
}
vlen=FileLenght(fp);
pid=malloc(num*sizeof(pid_t));
for(i=0;i<num;i++) {
if(!(pid[i]=fork())) {
fseek(fp,i*(NBYTES)*(vlen/num),SEEK_SET);
while(j<vlen/num) {
fscanf(fp,"%s",string);
printf("Process %d reading from file: %s\n",getpid(),string);
if(!strcmp(string,argv[3])) {
cnt++;
}
j++;
printf("(%d-%d) %d %s=%s\n",getpid(),getppid(),j,string,argv[3]);
}
fclose(fp);
exit(cnt);
}
}
fseek(fp,vlen*NBYTES,SEEK_SET);
for(i=0;i<num;i++) {
waitpid(pid[i],&status,0);
sum+=WEXITSTATUS(status);
}
printf("\nTotal found: %d\n",sum);
fclose(fp);
free(pid);
return 0;
}
输出(正确的计数应该是 4 而不是 5):
$ ./nf 5 file1 1224332
Process 18592 reading from file: 1224332
Process 18593 reading from file: 4363666
(18593-18591) 1 4363666=1224332
Process 18593 reading from file: 4363666
(18593-18591) 2 4363666=1224332
(18592-18591) 1 1224332=1224332
Process 18592 reading from file: 1224332
(18592-18591) 2 1224332=1224332
Process 18594 reading from file: 1224332
Process 18596 reading from file: ���ҿ�
(18594-18591) 1 1224332=1224332
Process 18595 reading from file: 2145515
(18595-18591) 1 2145515=1224332
Process 18595 reading from file: 1224332
(18595-18591) 2 1224332=1224332
(18596-18591) 1 ���ҿ�=1224332
Process 18596 reading from file: ���ҿ�
Process 18594 reading from file: 1224332
(18594-18591) 2 1224332=1224332
(18596-18591) 2 ���ҿ�=1224332
Total found: 5
【问题讨论】:
-
获取文件大小的方法比逐字节读取文件的每个字节更简单(也更快)。例如通过seeking 到最后并得到the current position。
-
感谢您的建议!这肯定会使程序更好更容易!但是,它并没有解决问题,我认为这与 fork() 和 fseek() 的使用有关……奇怪的是……有时有效,有时无效!