linux socket 처리에서 fork/select로 처리하는데 왜 자꾸 defunct가 날까요?
글쓴이: nayeona / 작성시간: 월, 2014/10/06 - 8:55오후
안녕하세요!
저는 linux os/ c언어/ 서버 socket을 다중접속이 되게 프로그램을 하였습니다.
흔히들 하시는 방식으로 fork/select를 이용하여 작성하였습니다.
동시간데 접속자도 많아야 10명 내외 입니다.
헌데 가끔 defunct가 발생을 합니다.
defunct가 발생되면 개수는 1개 입니다.
문제는 defunct가 발생되면 클라이언트에서 socket 접속이 안됩니다.
blocking socket에 의한 문제일까요?
errno = EINTR 오류로 인해 block된 상태일까요?
아니면...????
특별히 별다른 처리를 한것도 없습니다.
(혹시 제가 처리한 소스를 봐야 아시겠다면 소스를 올릴 수 있습니다.)
Forums:
음 ..
child 가 defunct 상태라면.. parent 에서 wait 을 못한건데...
signal handler 에서 loop 돌고 있던가.. 그럴 가능성이 있겠네요.
client 접속이 안 되는게.. connect 에서 block 된다는건지.. 바로 연결이 끊어진다는지 모르겠는데..
connect 에서 block 된다면, server 가 listen 하고 있는데 accept 를 못하고 있을 가능성이 높고..
바로 연결이 끊어진다면 listen 을 안 하고 있을 가능성이 높습니다.
strace 한 번 떠보시거나 accept 전에 디버깅 코드 하나 넣어 보시죠.
일단 server 의 parent 는 accept 에서 block 되어 있는 상태는 아닐 것 같습니다.
연결/해제가 빈번한 서버라면 가급적 fork 하지 마시고.. 그냥 select 에 multi-thread 로 처리하는게 깔끔합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
답변 감사합니다.
답변 감사합니다.
defunct 상황이 아주 불규칙하게 가끔 발생을 하게되는데, 오류가 발생이 되면
connect는 되는것 같습니다. connect 이후 데이터 송수신이 안되어 client에서
timeout이 발생하는 것 같습니다.
그런데 이런 생각도 아닐 수 있는것이 connect 요청을 받아 서버에서 accept하면
fork하여 프로세스를 만드는데, defunct의 개수가 늘어나거나 또는 접속에 대한
로그가 쌓여야 되는데 문제가 발생되면 이후 로그도 없고 defunct도 1개 입니다.
그래서 제 생각은 서버에서 accept 이후 fork하여 소켓을 자식에게 넘겨주고
부모에서는 해당 소켓을 close할 때 뭔가 문제가 생겨서 close를 못하고 있는
상황이지 않을까 추측됩니다.
추천해 주신 select(epoll)/multi-thread 방식을 검토하고 있습니다.
감사합니다.
음 ..
client 에서 connect 는 되는것 같다고 하셨는데, connect 에서 block 되었는지..
connect 에서 return 하고 다음 read 나 write 에서 block 되었는지 설명이 명확하지 않네요.
connect 에서 block 되었다면, server 는 accept 를 못하고 있는 상태일테니 fork 도 못했을것 같은데요.
디버깅은 최대한 정보를 모아서, 분석과 추론을 통해 가설을 세우고, 검증할 수 있는 수단을 만들고..
그걸 토대로 문제의 원인을 찾아가는 고단한 과정입니다. 추측만으로는 문제를 해결하기 어렵죠.
strace, lsof, tcpdump, ps 정도에 디버깅 로그 몇 줄이면 추측한게 맞는지 쉽게 확인할 수 있을겁니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기