티스토리 뷰

위는 시그널 함수의 원형이다.

Sigfunc는 커널이 실행할수 있도록 만들어 놓은 프로시져이다. (함수포인터)


signal함수가 정상적으로 리턴되면 Sigfunc형 포인터이다. 어떤 함수를 가리키는 포인터이다라고 생각하면 될것같다.


signal함수는 소프트웨어 인터럽트라고도 불린다. 어떤 프로세스에서 다른 프로세스에게 어떤 이벤트가 발생했다는것을 알려주기 위해서 시그널을 사용하기 때문에 그렇게 불린다. 또는 커널이 프로세스에게 인터럽트를 걸기도 한다.


int kill(pid_t pid, int sig);

(죽일 프로세스 아이디, 시그널 종류)


자식 프로세스가 죽었을때 SIGChild라는 이벤트가 발생하는데 커널이 이 이벤트가 발생하게 되면 signal 함수로 등록해 놓았던 시그널 핸들러를 실행시킨다.(이것을 시그널을 프로세스->프로세스에게 전달한다고 표현한다) 

없는경우 아무일도 하지 않거나 부모 프로세스를 종료시키거나 한다.(SIGCHILD의 경우 아무일도 하지 않는다 = 디폴트)


아무일도 하지 않을경우 문제가 생길수 있음.


자식 프로세스가 종료 됬는데 부모 프로세스에서 아무 일도 처리해주지 않기 때문에 메모리에서 없어 지지 않고 좀비 프로세스로 남아있다.


자식 프로세스가 종료되었을때 SIGCHILD이벤트가 발생하고 아까 signal함수로 이런이벤트엔 이런 시그널 핸들러를 실행시키겠다는 의미를 커널에게 전달했으므로, 커널이 그 핸들러를 실행시키게 되는데, 이 핸들러 안에서 좀비 자식 프로세스를 메모리에서 깔끔하게 free시키는 wait시스템콜을 호출하게 한다.


int stat; 

pid = wait(&stat); 


wait시스템콜이 하는 일은 자식 프로세스가 어떤 상태로 종료되었는지 stat에 값을 세팅하고(bit별로)

wait시스템콜을 호출하고 있는 부모 프로세스의  자식 프로세스 아이디를 리턴시킨다.


Signal함수가 추가된 서버 프로그램.

Signal함수의 의미 : SIGCHLD이벤트가 발생했을때 sig_chld라는 시그널 핸들러를 실행시켜라

그렇기 때문에 이벤트가 발생하기 전에 Signal함수를 실행시켜야 한다. (자식 프로세스가 죽기전)

이 함수가 실행되면 커널이 이런 이벤트가 발생했을때 이런 핸들러를 실행시키라고 적어놓게 된다.


위의 프로그램이 시그널 핸들러이다. 바로 위의 서버 프로그램에서 signal함수로 sigchld이벤트에 이 시그널 핸들러를 등록했었다.

pid는 SIGCHLD이벤트를 발생시킨 방금전 죽은 자식 프로세스의 프로세스 아이디가 들어가고

stat에는 그 자식 프로세스가 어떤 상태로 종료되었는지가 값으로 세팅 되어있다.


wait 시스템콜(자식이 종료될떄까지 기다리고있다라는 의미)은 부모 프로세스에서 실행 되는것이다. 

부모 프로세스에서 wait시스템콜을 호출하고 있으면 자식 프로세스를 좀비 상태로 놔두지 않고 깔끔하게 죽여준다.

SIGCHLD이벤트를 처리하는 시그널핸들러가 부모 프로세스에 등록되어 있지 않으면 아무일도 하지 않게 되는데, 

그런 경우 자식 프로세스의 정보를 일정시간동안 유지시킨다. 


웹서버 같은 경우에 많은 자식프로세스가 만들어질수있는데 부모프로세스에서 SIGCHLD 시그널핸들러를 등록해 놓지 않게 되면

자식 프로세스가 죽어도 아무일도 안일어나고  많은 좀비 프로세스가 나타난다.


wait 시스템콜은 자식 프로세스가 죽기를 기다린다. wait시스템콜을 호출하는 순간에 종료된 자식 프로세스가 있는 경우에는

그 자식 프로세스의 정보를 stat에 세팅해놓고 그 종료된 자식 프로세스의 아이디를 리턴시키고 끝이다.


wait를 호출했는데 종료하지 않은 자식 프로세스 1개이상이 있을때 종료할때까지 블락되서 기다린다.

Concurrent서버는 동시다발적인 클라이언트의 요구 때문에 다수의 자식 프로세스가 만들어지게 된다.(웹서버의 경우)

다수의 자식 프로세스가 있는데 wait를 할경우 

다수의 자식 프로세스중 하나가 죽게 되면 SIGCHLD발생 -> 커널이 부모프로세스의 시그널 핸들러 실행-> wait() 호출 -> 

제일 처음 죽은 자식 프로세스는 제대로 리턴됨. -> 아직도 종료 안된 자식프로세스가 여러개 남아있다 -> 그냥 기다린다 -> 

시그널 핸들러를 호출한 부모 프로세스는 다른일을 할 수가 없음.


이러한 일들을 피하기 위해서 waitpid라는 시스템콜을 나중에 추가하였다. 

처음에 wait 시스템콜을 만들때는 웹서버와 같은 엄청나게 바쁜 서버가 없었기 때문에 그냥 저런식으로 만들었다.














댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함