C 带有fork()的fseek()工作不正常
将fseek()与fork()结合使用(实际上使用的是XUbuntu 15.10)时,我遇到了一个问题。 我必须编写一个程序,从文件(“file1”)中读取一系列数字(在不同的行中),并报告与特定字符串匹配的行数,作为参数传递。C 带有fork()的fseek()工作不正常,c,process,fork,fseek,C,Process,Fork,Fseek,将fseek()与fork()结合使用(实际上使用的是XUbuntu 15.10)时,我遇到了一个问题。 我必须编写一个程序,从文件(“file1”)中读取一系列数字(在不同的行中),并报告与特定字符串匹配的行数,作为参数传递。 我称之为“nf”的程序必须按如下方式调用(./nf number\u of\u processes file1 match\u string)。 程序应创建多个\u进程的子进程(使用fork()),每个子进程应处理文件的单个部分(即,如果\u进程的数量为5,且文件有15
我称之为“nf”的程序必须按如下方式调用(./nf number\u of\u processes file1 match\u string)。
程序应创建多个\u进程的子进程(使用fork()),每个子进程应处理文件的单个部分(即,如果\u进程的数量为5,且文件有15行,则每个子进程应处理文件的15/5=3行)。
然后,子进程应将结果报告给父进程,父进程将打印文件中出现的次数。
现在,问题是:我使用fseek编写程序(每个子进程在文件中找到正确的位置,并开始分析单个节的长度),但有时它似乎工作正常,而另一些子进程打印错误的结果,就像它以错误的方式读取文件一样(多次读取或读取垃圾而不是数字字符串)。。。
你知道为什么会这样吗?
先谢谢你。
这些文件如下所示:
文件1: nf.c:
由于
fork()而在进程之间共享文件描述符时
,文件描述符的所有属性在副本之间共享,包括当前偏移量。。因此,程序中的所有子进程都试图在同一时间查找并读取同一文件描述符中的数据,从而导致各种意外结果
要解决此问题,您需要延迟打开文件,直到您已经分叉,或者
dup()
分叉后为每个子进程创建独立副本的文件描述符。这可能是由指针fp造成的。因为每次创建子线程时,子线程都使用相同的fp,所以有时打印4,有时打印5,有时打印3,还有2。更简单(更快)与逐字节读取文件的每个字节相比,获取文件大小的方法。例如,到结尾和获取。感谢您的建议!这肯定会使程序更好、更简单!但是,它并不能解决问题,我认为这与使用fork()和fseek()有关…奇怪的是…有时有效,有时无效!非常感谢!我在分叉后移动了文件开口,解决了问题!
1224332
1224332
4363666
4363666
1224332
5445774
2145515
1224332
2145515
1111111
2145515
9789899
2344444
6520031
4363666
#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;
}
$ ./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