2013-02-10 2 views
1

저는 명령 행에서 숫자를 취하고 fork()를 사용하여 숫자의 자릿수를 합친 프로세스 체인을 작성합니다. 지금까지, 그것은 다음과 같다 :숫자에서 숫자의 합을 찾기 위해 fork() 사용하기

내 시스템의 책에서 무엇을 이해할 수에서
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main(int argc, char* argv[]){ 

    if(argc != 2){ 
    printf("Usage: sod [number] \n"); /* -o sod when compiled */ 
    exit(1); 
    } 

    pid_t childpid = 0; 
    int sum = 0; 

    int i; 
    for(i = 0; i < strlen(argv[1]); i++){ 
    /* atoi needs a string */ 
    char str[2]; 
    str[0] = argv[1][i]; str[1] = 0; 
    sum += atoi(str); 
    if(childpid = fork()) 
     break; 
    } 

    wait(NULL); 
    printf("sum: %d\n", sum); 
    exit(0); /* probably redundant... */ 
    return 0; 
} 

의 경우 문이 프로세스는 각각의 부모가 한 아이를 가질 수 있습니다 (체인에 있음을 보장하고, 그 선 아래로 계속) fork()은 자식 프로세스의 id를 자식 프로세스로 반환하고 0은 자식 프로세스로 반환하기 때문입니다. 따라서, 과제의 결과는 부모/제로가 아닌 사실과 루프에서 휴식을 강제로 :

if(childpid = fork()) 
      break; 

나는 wait(NULL) 전화를 추가하기 전에, 함수가 순서대로 반드시, 합계 여러 줄의 인쇄 , 나는 다른 시간에 프로세스가 끝나기 때문에 예상해야한다고 생각합니다. 흥미롭게도, 내가 11221121과 같은 큰 숫자의 프로그램을 호출하면, 때로는 일부 합계를 출력하고, 중간에 쉘 프롬프트를 출력하고, 무한대처럼 매달리기 전에 몇 가지를 더 인쇄합니다 루프 : 이런 일이 될 수있는 이유에

[nvj]@sun ~/313/sod> (12:15:21 02/10/13) 
:: sod 11221121 
sum: 1 
sum: 2 
sum: 4 
sum: 6 
sum: 7 
sum: 8 
sum: 10 

[nvj]@sun ~/313/sod> (12:15:24 02/10/13) 
:: sum: 11 
sum: 11 
[hangs here...] 

내 유일한 추측은 뭔가 시간 초과 또는 다른 사람을 위해 기다릴 필요가 가지 틀에 박힌 생활에지고 있다는 점이다. 프로그램이 실제로 종료되도록 (그리고 어떤 종류의 순서로 합계를 인쇄), 나는 wait(NULL) 호출을 추가했습니다. 내가 이해할 수있는 것으로부터, 부모는 계속하기 전에 모든 아이들을 기다려야합니다. 당연히,이 마지막으로 생성 된 아이가 완료로 먼저 인쇄 할 실제 금액을 초래하고 순서대로 나머지 추적을 할 수 있습니다 :
[

nvj]@sun ~/313/sod> (12:25:02 02/10/13) 
:: sod 12389492182398 
sum: 69 
sum: 69 
sum: 61 
sum: 52 
sum: 49 
sum: 47 
sum: 39 
sum: 38 
sum: 36 
sum: 27 
sum: 23 
sum: 14 
sum: 6 
sum: 3 
sum: 1 

다행히,이 프로그램은 실제로이 경우에 끝납니다. 그러나 실제 총액을 가진 아이가 돌아오고 결과를 표시 할 때 아이를 끝내는 방법이 있습니까? 나는 평평한 외침 exit (당신이 볼 수 있듯 ...)과 같은 것들로 실험했지만 이것은 자식 프로세스보다 다른 '영역'에서 작동하는 것으로 보이며 첫 번째 인쇄 후에 즉시 발생하지 않습니다.

+1

문자열을 만들고 'atoi'를 사용하여 char의 숫자 값을 가져올 필요가 없습니다. argv [1] [0] - '0' '(그리고'argv [1] [0] = '0 '') –

+1

사용법 메시지에 실행 파일 이름을 하드 코딩하는 것은 나쁜 습관입니다. argv [0]'을 사용하여 이름을 얻는다. –

+0

'for (i = 0; i

답변

2

fork()을 사용하면 숫자의 숫자를 합산하는 데 꽤 비싼 방법입니다. 대신 웹 서비스로 할 수 있습니다. 그 속도는 느려질 것입니다.

그래서 훈련 연습으로 각 어린이가 자신의 변수 사본을 가지고 있다는 것을 깨달을 필요가 있습니다. N 번째 아이가 부모 프로세스의에 sum의 값에 영향을 미칠 수있는 방법은 없습니다 - 공유 메모리에 도착하지 않는 등

당신이 말할 때 :

sum: 10 

[nvj]@sun ~/313/sod> (12:15:24 02/10/13) 
:: sum: 11 
sum: 11 
[hangs here...] 

이 쉘은 사전에 당신을하라는 메시지가, 귀하의 의견을 기다리고 있습니다. 'hang'쉘에 echo Hi을 입력하면 Hi이 표시되고 정상적으로 프롬프트됩니다. 그것은 단지 마지막 아이가 글쓰기를 끝내기 전에 부모 프로세스가 끝났음을 의미합니다.

을 넣기 전에 첫 번째 프로세스가 분기되고 루프를 빠져 나가서 그 값을 출력 한 다음 종료하여 쉘이 다시 프롬프트 할 수 있도록합니다. 그 사이에, 첫번째 아이는 그것의 재료를하고 있었고 두번째 아이는 그것들을 분기하고 나가는 것이었고, 어떤 일이 일어나는 순서는 스케줄러에 의해 결정됩니다.

wait()을 사용하면 자녀 (및 자녀 (및 자녀) (및 자녀) ...)))가 출력을 완료하고 응답을 결정적 순서로 되돌립니다.

마지막 자식은 이전 자식에 의해 누적 된 숫자의 합계를가집니다. 이는 마지막 자식 만 최종 합계를 얻기 위해 아무것도 인쇄 할 필요가 없음을 의미합니다.

exit(0);return(0); 중 하나가 중복됩니다. exit(0); 대신 return(0);을 사용하는 것이 좋습니다.

관련 문제