waitpid 에 관련 하여...
여러가지로 많은 정보를 얻고 있습니다.
waitpid 관련 하여 여쭈어 볼려구여....
먼저 특정 시간을 스케줄링을 하여 순차적으로 fork 시키는 스케줄러를 만들었습니다.
프로세스 동기화 때문에 꼭 선행된 프로세서가 끝나야만 다음 프로 세스가 돌아가게 했는데 waitpid 를 거치지 않고 다음 프로세서가 실생되어 도는 문제가 발생 하였습니다.
프로그램 로직은 대략 이렇습니다.
int main(int argc, char *argv[]) {
.......
signal(SIGCHLD,sigchld_handler);
signal(SIGHUP,SIG_IGN);
#ifdef SIGTTOU
signal(SIGTTOU,SIG_IGN);
#endif
signal(SIGTTIN,SIG_IGN);
while ( 1 ) {
'''''''''''''''
if (시간 check 조건) {
if ((child1 = fork()) == 0) /* child1 */
execl((char *) "실행파일 디렉토리", (char *) "실행파일1", char *) "Option", (char *) 0);
if ((child2 = fork()) == 0) /* child2 */
execl((char *) "실행파일 디렉토리", (char *) "실행파일2", char *) "Option", (char *) 0);
waitpid(child1, &status, NULL);
waitpid(child2, &status, NULL);
if ((child3 = fork()) == 0) /* child3 */
execl((char *) "실행파일 디렉토리", (char *) "실행파일3", char *) "Option", (char *) 0);
''''''''''''''''''
} /* end if */
''''''''''''''''''
} /* end while */
''''''''''''''''''
}
제가 생각 하기에 이런 로직이라면 child1 과 child2 가 waitpid 에서 끝나는걸 기다렸다가 child3 을 수행 하는 것으로 알고 있습니다.
헌데 child1 또는 child2 가 끝나지 않은 상태에서 child3 이 돌구 있는 상황이 벌어 졌습니다. 왜 이런 일이 일어나는지 모르겠거덩요 ..
첨에는 sig_handler 와 waitpid를 같이 쓰는 문제가 아닐까 생각 했었는데 그렇다는 구체적인 이유를 찿지 못했습니다.
하나 더 궁금한건 waitpid 의 리턴값을 찍어 봤더니 "-1" 이 나오더라구여
이게 정상인지 아닌지 모르겠습니다 참고로 waitpid 의 첫번째 아규먼트인 child 프로세서의 pid 는 정상으로 찍혔었습니다. child 프로세서의 pid 가 -1 이 아닌 정상값으로 넘어 갔는데 waitpid 값이 -1 이나는게 정상인지 아닌지 모르겠습니다.
고수님들의 조언 부탁 드립니다.
일단 os의 종류와 버전을 명시해 주시면 좋겠습니다.os 마다 sig
일단 os의 종류와 버전을 명시해 주시면 좋겠습니다.
os 마다 signal에 대한 방식이 조금씩 다를 수 있습니다.
그리고 waitpid()에서 -1 return이라면 뭔가 잘못된 것입니다.
perror()로 오류의 내용을 출력해 주세요.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
- 먼저 프로세스가 돌고 있는 OS 의 version 은 Sun OS
- 먼저 프로세스가 돌고 있는 OS 의 version 은
Sun OS 5.7 과 5.8 입니다.
기본적으로 올린 소스는 Child 프로세서를 2개가 실행 시키고 그걸 그다렸다가
1개의 child를 포크 시킨것으로 올렸지만 실제로는 2개를 실행시키고,
그것이 끝난 다음 2개의 프로세서를 포크시키는 로직 입니다.
- perror 의 메세지 입니다. perror 는 waitpid 한다음 찍어 봤구여..
Error Msg: Interrupted system call <- child1 을 waitpid 후 찍은 에러
Error Msg: Interrupted system call <- child2 을 waitpid 후 찍은 에러
Error Msg: Interrupted system call <- child3 을 waitpid 후 찍은 에러
Error Msg: No child processes <- child4 을 waitpid 후 찍은 에러
- 다음은 handler 에서 찍은 메세지 입니다.
> child 537 terminated
> WIFEXITED(stat) is non zero(normal exit).
> child 680 terminated
> WIFEXITED(stat) is non zero(normal exit).
> child 743 terminated
> WIFEXITED(stat) is non zero(normal exit).
> child 673 terminated
> WIFEXITED(stat) is non zero(normal exit).
혹시 해서 handler 의 소스도 올립니다.
============================================
void sigchld_handler() {
int stat, res;
pid_t pid;
signal(SIGCHLD, sigchld_handler);
while ( ( pid = waitpid( -1 , &stat , WNOHANG ) ) > 0 )
printf("> child %d terminated\n", pid);
if((res = WIFEXITED(stat)) != 0)
printf("> WIFEXITED(stat) is non zero(normal exit). \n");
return;
}
=============================================
지금 문제는 main, sigchld_handler양쪽에서 모두 wait
지금 문제는 main, sigchld_handler양쪽에서 모두 waitpid()를 호출하는것이 문제로 보입니다.
한쪽에서만 사용하시면 될것 같네요.
sigchld_handler에서만 waitpid하시려면
이런식으로 하시구요.
main에서만 하실 거라면... sigchld_handler에서는 waitpid 함수를 사용하지 마시고, main에서만 사용하시면 될겁니다. 이때 다음처럼 사용하시는게 안전해 보이네요...
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
첨언하면 요즘엔 signal()보다는 sigaction()을 많이 사용합
첨언하면 요즘엔 signal()보다는 sigaction()을 많이 사용합니다.
signal()은 해당 signal이 발생했을때 해당 signal에 대한 action을 SIG_DFL로 바꾸기 때문에 sighandler에서 다시 signal()을 호출하는데 sigaction()은 한번 설정으로 그 값이 바뀌지 않습니다.
Linux에서도 signal()이 위와 같다고 manpage에 나와있는데 제가 작업하는 환경에서는 signal()이 sigaction()과 동일하게 작동하더군요...
어쨌든 요즘엔 signal() 보다 sigaction()을 많이 사용합니다.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
좋은말씀 감사 함다
좋은 말씀 감사함다..
도움이 많이 되었습니다. 꾸뻑 ^&^ ...
해결되셨다니 다행입니다.waitpid() 연산자체가 다른 CHIL
해결되셨다니 다행입니다.
waitpid() 연산자체가 다른 CHILD 의 중지로 SIGCHLD 를 받아 중지되고 waitpid() < 0 면서 errno == EINTR 로 되었기 때문인것 같습니다.
waitpid() 명령은 특정 CHILD 만을 기다리는 함수로 쓰이기는 하나, 해당 CHILD 를 기다리는 도중에 SIGCHLD 가 발생해서 시그널핸들러로 점프했다가 처리하고 나서 되돌아왔고 이때 errrno == EINTR 로 설정된 듯합니다.
즉, 기다리고자 하는 CHILD 를 처리하고 나서 정상적으로 return 한게 아니기 때문입니다.
내 자식들도 나처럼 !!
댓글 달기