2013-10-07 1 views
0

2 개의 인수를 입력으로 입력해야하는 곳은 다음과 같습니다. 첫 번째 인수는 숫자입니다. 이 x 호가 2의 배수이면 fork를 사용하여 15 개의 하위 프로세스가 작성됩니다. 번호가 3의 배수이면 10 개의 프로세스가 생성됩니다. 번호가 5의 배수이면 7 개의 프로세스가 생성됩니다. 두 번째 인수는 크기 (바이트)를 생성 된 프로세스의 수로 나누고 각 하위 프로세스가 파일의 한 부분을 읽는 경우 파일의 일부를 변수에 저장하고 마지막으로 부모가 모든 그 변수의 텍스트. 예를 들어 ./p 5 /home/directoryFile.c를 사용하여 프로그램을 실행합니다. 그래서 7 개의 자식 프로세스가 있고 파일 크기가 700 바이트라고 가정 해 봅시다. 즉, 모든 하위 프로세스는 100 바이트를 읽어야하며, 내용을 변수에 저장하고 부모는 모든 콘텐츠를 함께 표시합니다. 문제는 부모의 모든 내용을 표시해야하는 변수 textToSend가 아무 것도 표시하지 않는다는 것입니다. 자식의 sprintf 행에 문제가 있어야한다고 생각합니다.프로세스 포크, 파일 읽기, 내용 표시 안함

//gcc Test.c -o p 
//./p 5 /home/directoryFile.c 

#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <dirent.h> 
#include <sys/wait.h> 

int main(int argc, char *argv[]) 
{ 
    int studentId, children = 0, j, i, childNumber[15], fdFile, fdread; 
    float bytesToRead; 
    char directory[50]; 
    char *buffer = malloc(256), *textToSend = malloc(256); 

    system("clear"); 

    if(argc-1 < 1) 
    { 
     printf("\nSome arguments are missing\n"); 
     return EXIT_FAILURE; 
    } 

    studentId = atoi(argv[1]); 
    strcpy(directory,argv[2]); 

    if((studentId%2) == 0) 
    { 
     children = 15; 
    } 
    else 
    { 
     if((studentId%3) == 0) 
     { 
      children = 10; 
     } 
     else 
     { 
      if((studentId%5) == 0) 
      { 
       children = 7; 
      } 
      else 
      { 
       printf("\nStudentId is not multiple of 2, 3 o 5\n"); 
       return EXIT_FAILURE; 
      } 
     } 
    } 

    struct stat fileInfo; 
    stat(argv[2],&fileInfo); 

    bytesToRead = fileInfo.st_size/children; 

    printf("children: %d\n",children); 
    printf("File Size: %lld\n",(long long int) fileInfo.st_size); 
    printf("Bytes: %.2f\n",bytesToRead); 

    fdFile = open(directory,O_RDONLY); 

      if(fdFile == -1) 
      { 
       printf("\nError opening the fileo\n"); 
       return EXIT_FAILURE; 
      } 

    for(i=0;i<children;i++) 
    { 
     childNumber[i] = fork(); 

     if(childNumber[i] == -1) 
     { 
      printf("\nError creating the child process\n"); 
      return EXIT_FAILURE; 
     } 

     if(childNumber[i] == 0) 
     { 
      fdread = read(fdFile,buffer,bytesToRead); 

      if(fdread == -1) 
      { 
       printf("\nError reading the file\n"); 
       return EXIT_FAILURE; 
      } 

      printf("%s",buffer); 
      //printf("\n\n------------------------\n\n"); 

      sprintf(textToSend,"%s%s",textToSend,buffer); 

      return EXIT_SUCCESS; 
     } 
     else 
     { 
      //waitpid(childNumber[i],NULL,WNOHANG); 
     } 
    } 

    printf("\nThis is the content of the file: %s\n",textToSend); 

    close(fdFile); 

    for(j=0;j<children;j++) 
    { 
     wait(NULL); 
    } 

    return EXIT_SUCCESS; 
} 

어떻게 될 수 있습니까? 버퍼가 파일의 일부를 올바르게 표시하고 있습니다 ... sprintf 기능이 될 수 있습니까?

+0

나는이 질문을 이전에 totday 이미 읽지 않았는가 : http://stackoverflow.com/questions/19217281/sprintf-and-buffer-from-files – alk

답변

1

sprintf을 사용하여 프로세스간에 공유되지 않는 로컬 버퍼로 인쇄합니다.

fork 귀하의 자녀는 비공개 인 모든 부모 메모리의 전체 개인 복사본을받습니다. 특별히 공유 메모리로 할당되지 않는 한 모든 메모리는 기본적으로 비공개입니다. 그런 다음 모든 프로세스에서 액세스 할 수있는 동일한 메모리를해야합니다

char * textToSend = mmap(NULL, 256, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); 

공유로 당신이 그것을 할당 할 경우

.

다른 모든 프로세스에 버퍼의 시작 부분이 이동했음을 알려줘야하므로 추가 공유 변수와 동기화 된 액세스가 필요합니다. sprintf으로 텍스트를 추가하지 않는 순간에 이전 내용을 덮어 쓰게됩니다.

결국 다른 프로세스의 결과를 함께 풀려면 공유 메모리가 아닌 파이프 (pipe(2))를 사용하는 것이 좋습니다.