fork()/wait() 질문 ?

lapex의 이미지

void func(int n)
{
    for(int j=0; j < n; j++) {
        if ((pid[j] = fork()) == -1)
            perror("multi client forks");
        if (pid[j] == 0) { /* child */
                // do something..
        } else {
            /* 1. wait() */
        }
    }

    for(int j=0; j < n; j++)
        if (pid[i])
            /* 2. wait() */
}

int main(void)
{
    pid_t pid[NUM_OF_CLIENT];

    for (int i=0; i < NUM_OF_CLIENT; i++)
        func(i);

    return 0;
}

대충 슈도 코드식으로 짜보면 위와 같은 로직을 갖고 있습니다.

제가 원하는 것은 main() 내에서 func() 를 호출할 때
func(0) 의 child 들이 다 마친후에
func(1) 가 수행되고, 또 그 child 들이 일을 다 마친후에
func(2) 가 수행되는 식으로 프로그램을 만들고 싶은데

func() 내에서는 fork() 로 생성된 프로세스끼리 계속
context switch 를 하면서 돌고 있어야 합니다.

질문이 조금 애매한 것 같으니 다시 정리하자면
func() 내에서 for 문을 돌면서 생성된 자식 프로세스가
일을 다 마친후에 func() 을 끝내고
main() 내의 루프로 돌아가고 싶은 루틴을 짜고 싶은데

1.wait() 위치에 쓰는 것이 맞나여 아님
2.wait() 위치에 쓰는 것이 맞는 건가여

아님 다 틀린가여

pynoos의 이미지

wait 은..

SIGCHLD handler를 등록하여 거기서 해주는 것이 좋습니다.

운형의 이미지

2번에 달경우 문제가 좀 있네요(물론 1번도 문제가 있지만.. -_-")

2번경우 자식 프로세스가 동시에 3개이상 죽는 경우 시그널이 중첩되지 않는 관계로 부모가 3번째 이후 자식의 죽음은 알지 못하게 될겁니다.
이때 waitpid에 WNOHANG을 달고 루프를 돌리면 수거는 다 되죠.

1번경우는 시체는 정말 깔끔히 수거하는 반면 생성된 자식이 전부 죽을 때까지 부모는 아무일도 못할겁니다.

시그널을 좀 이용하면 부모도 자기 할일 다하면서 자식 시체 수거 잘하는 코드가 나올껀데...

도움이 되셨을런지..

Do you think that's the air you are breathing now?

seeker의 이미지

#include <signal.h>
#include <sys/wait.h>

main부분에...
struct sigaction act ;
act.sa_handler = sighandler;
act.sa_flags = 0;
sigemptyset( &act.sa_sigset );
sigaction( SIGCHLD , &act , 0 );

시그널핸들러를 ...
void sighandler(int signo )
{
while ( waitpid( -1 , 0 , WNOHANG ) > 0 ) ;
}