我在使用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編寫程序(每個子進程在文件內部找到它的正確位置,並開始分析它的長度爲單個部分),但有時它似乎工作,而其他一些它打印出不正確的結果,就像是以不正確的方式讀取文件(多次讀取文件或讀取垃圾而不是數字字符串)...
您知道爲什麼會發生這種情況?
非常感謝。
的文件是以下物質:
file1的:fseek()帶叉子()不能正常工作
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
獲取文件大小的方法比逐字節讀取每個字節更容易(也更快)。例如,通過[尋求](http://en.cppreference.com/w/c/io/fseek)並獲取[當前位置](http://en.cppreference.com/w/c/) IO/FTELL)。 –
感謝您的建議!這一定會讓程序變得更好更輕鬆!然而,它並沒有解決這個問題,我認爲這個問題與使用fork()和fseek()有關......奇怪的是...有時它有效,有時候不行! – ProgProb