멀티쓰레드를 이용한 다중접속 socket서버에서 문제....
글쓴이: hitman7 / 작성시간: 수, 2006/03/22 - 9:20오전
제목에 표시된 대로의 프로그램입니다.
상황은 서버를 실행 시킨후 aging을 걸기위하여 10초 주기로 접속을 한후 냅다 접속을 끊어버리는 윈도그용 클라이언트 어플리케이션을 10개 가량 실행 합니다.
처음에는 잘 동작하다가 한 5분 후부터 응답을 보내지않고 뻗어버리네요. 뻗기전에는 소켓들도 잘 해제하다가 뻗자마자 소켓들이 CLOSE_WAIT 상태에 빠져 버리고요.
가능하시면 다른 조언들도 부탁드리겠습니다.
(실행중에 메모리가 계속 차네요...메모리 릭이라도 있는걸까...워낙 단순해서 없을것 같은데 말이죠..)
소스가 써지질 않아서..첨부합니다..ㅠ,.ㅠ
main은 서버측이고
client.c는 10초마다 불리워지는 함수입니다. 윈도우측이고요.
File attachments:
첨부 | 파일 크기 |
---|---|
main.c.txt | 2.02 KB |
client.c.txt | 537바이트 |
Forums:
혹시나 싶어서
혹시나 싶어서 그러는데, main()에서 accept()를 하고서 자식 스레드에게 &sock_c를 넘겨주는 것, 위험하지 않을까요? 자식 스레드가 시작되기 전에 주스레드가 또 다른 연결을 accept()해서 sock_c값이 바뀌어 버리면 소켓 하나가 둥둥 뜨게 되고, 다른 소켓 하나는 두 스레드가 동시에 사용하게 될 테니까요.
----
$PWD `date`
$PWD `date`
흠. 그것은
흠. 그것은 문제겠네요. 메모리가 새는 부분이 될수 있겠습니다. 하지만 5분 만에 뻗는것이 영. 메모리를 한 10메가 정도 쓴다음에 뻗으니깐요. 조치 해보도록 하겠습니다. 감사합니다.
와 같이 했는데 증상은 나아지지 않았네요.. :(
far and hard way
위에님이
위에님이 지적하신문제는 적용하신코드로는 해결되지 않습니다.
다른어떤방법을 강구하셔야합니다.
뭐간단히는 Thread call 다음에 usleep 를 주는방법도 있지만.
저같으면 sock 이 int 인점을 착한하여 Call by reference보다 Direct 로 값을 넘겨줄수가 있겠죠..
물론 님이 10초에 한번씩 콜한다고 하셧나요? 그러면 매우긴시간이기때문에 위에서 그문제가 아닐가능성은높지만..말이죠..
----------------------------------------------------------------------------
5분후에 서버가
5분후에 서버가 이상동작한다면, 약 1분 경과 부터, 4분까지 1분정도 단위로 netstat -na해서 특이 사항을 올려주세요. 혹시나 해서 말입니다. ㅎ
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
별 특이 사항은
별 특이 사항은 없습니다..
서버가 동작하는 상황에서는
포트에 일반적인 연결이 되어 있는 상황 즉 ESTABLISHED 로 몇개가 떠 있습니다. (접속보다는 적게..워낙 접속을 하자마자 끊어지니깐요)
그러다가 서버가 동작을 멈추게되면
당연한 이야기이지만 접속을 처리하지 못하여 클라이언트를 종료 시키지 않은한 계속해서 CLOSE_WAIT 상태가 나타납니다.
아래는 서버가 정상 동작중일 때의 netstat -an의 결과입니다.
아래는 서버가 동작을 멈춘후의 netstat -na의 결과 입니다.
far and hard way
이렇게 한번 해보세요..
쓰레드 함수내에
변수 선언후..
pthread_detach(pthread_self()); <-- 이걸 추가해보세요.,,,
쓰레드 함수내에변수
현재 30개 연결에 15분간 버티고 있습니다. 감사합니다 :)
그런데 여기에서 질문이 하나 더 있습니다.
쓰레드가 종료되는 순간 쓰레드에서 사용되는 자원이 반환이 되어야 하는게 정상일텐데요. 왜 굳이 pthread_detach()를 사용해야 문제점이 없어지게 된걸까요? 어떠한 상황에서
return 0;
pthread_exit();
pthread_detach();
를 사용해야 할까요?
far and hard way
쓰레드 관련하여
쓰레드 관련하여 아래글을 참고하세요.
http://kldp.org/node/60444
http://kldp.org/node/63142
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
제가 보기엔..
Call by reference 문제가 아니라.. 쓰레드가 생성된후 종료되는 과정이 문제인거 같습니다..
제가 pthread_detach(pthread_self())를 조언한것은 이렇게 하면 쓰레드가 함수 실행후 알아서 종료하기 때문입니다.
하지만 이렇게 안하고 pthread_join()같은것으로 나갈려면 쓰레드가 종료댈때까지 기다려 줘야합니다.
물론 문제의 증상은
물론 문제의 증상은 call by reference 에의한 문제는 아닌것으로 보입니다.
하지만 누가 맨처음 지적하셨듯이 그곳에는 치명적인문제가있습니다.
----------------------------------------------------------------------------
혹시, 이문제는 어떻게 되나요?
p_thread 변수가 맘에 걸립니다.
쓰레드를 생성할때, 매번 p_thread의 공간을 만들어 줘야 하지 않나요?
서버의 OS가 무엇인지요?
예전에 저도 HP에서 잘 돌아가던 소스를 레드햇 9에 포팅을 한 적이 있었습니다... HP에서는 잘 돌아갔는데 리눅스에서는 어느 순간에 모든 프로세스가 락이 걸리는 겁니다... 그 문제로 1주일동안 고민하다가 NPTL의 적용여부에 따라서 리눅스에서의 쓰레드 동작 방식이 다르다는 것을 알았지요... 그래서 레드햇 9에서 레드햇 엔터프라이즈 3이상으로 OS를 업그레이드 했습니다... 별다른 문제없이 죽지도 않고 잘 돌아갔습니다... 리눅스에서의 작업이라면 그리고 쓰레드를 사용하시니깐 NPTL을 의심해볼만도 합니다... 아는것이 없어서 이정도밖에... *^^*
---------------------------------------------------------------------
여기가 어디지? 집에는 갈 수 있을까?
여기가 어디지? 집에는 갈 수 있을까?
리턴값을 체크하세요.
pthread_create 함수의 리턴값을 체크하세요.
accept한 소켓과 thread에게 넘기는 socket을 dup해도 됄꺼 같은데요...
mutex락을 사용하지 않고...
sock = accept(...); 후에
sockd = dup(sock); 후에
pthread_create(...., (void *) &sockd); 해줘도 됄꺼 같은데요..^^;;
마지막으로 close(sock); 해주고요^^;;
댓글 달기