[질문] 서버의 cpu 점유율이 높아집니다..
글쓴이: yhjj777 / 작성시간: 금, 2004/07/23 - 7:55오후
흐.. 갑자기 cpu 점유율이 높아지는데요.. 쓰레드 문제와 센드큐과 꽉 찼을때의 문제라고 생각을 하고 그 부분을 집중적으로 손 봤는데.. 안잡히더군요.. 그래서 방금전 그런 현상이 벌어졌을때 truss로 해당 프로세스가 뭘 하고 있는지 살펴보니.. write를 계속 무한으로 하는데 에러 메세지가 socket is not connected라네요.. kqueue에 논블락킹 소켓, 멀티 쓰레딩 환경입니다... 이런 현상이 벌어지려면 선행 조건에 무엇이 있을까요??
write(1,0x9ce4000,81) ERR#57 'Socket is not connected' gettimeofday(0xbfaf8de8,0x0) = 0 (0x0) write(1,0x9ce4000,81) ERR#57 'Socket is not connected' gettimeofday(0xbfaf8dc8,0x0) = 0 (0x0) write(1,0x9ce4000,81) ERR#57 'Socket is not connected' gettimeofday(0xbfaf8dc8,0x0) = 0 (0x0) write(1,0x9ce4000,81) ERR#57 'Socket is not connected' gettimeofday(0xbfaf8dc8,0x0) = 0 (0x0) write(1,0x9ce4000,81) ERR#57 'Socket is not connected'
Forums:
정확한 상황은 파악할 수 없지만.. 혹시나 해서 글 올려봅니다.n
정확한 상황은 파악할 수 없지만.. 혹시나 해서 글 올려봅니다.
non-blocking의 소켓에 connect()를 호출했을 경우에는..
실제 connect()가 이뤄졌는지 검사를 해야 합니다.
connect의 return 값이 0일 경우 connect 완료.
return < 0, if errno == EWOULDBLOCK or EINPROGRESS 일 경우
select로 해당 non-blocking 소켓 디스크립터에 event 발생 여부를 확인후에
getsockopt의 SO_ERROR option으로 error 여부를 체크해야 합니다.
실제 connect가 이뤄진 상태가 아닌데.. 거기다 write를 하는 것은.. -_-a;
앗. 실수했습니다. 논블락킹 소켓이 아니라 블록킹 소켓입니다. 치명적인
앗. 실수했습니다. 논블락킹 소켓이 아니라 블록킹 소켓입니다. 치명적인 실수였네요..
생각해보니까 이런 현상이 일어나는게 멀티쓰레딩이라서 그런것같네요. 리시브할때와 센드할때가 다른 쓰레드로 돌아가는데,, 센드할때는 그 소켓이 클로즈된 소켓인지 모르고 그 소켓이 계속 센드를 날릴테고 그 부분에서 블락이 되버려서 생긴 문제 같습니다.. 일단 이 문제는 소켓에 액티브한지 끊어졌는지를 구분할수있는 플래그를 둬서 플래그값이 끊어졌다면 센드하지 않는걸로 변경하였습니다.. 지금 이 코드를 적용하고 테스트중인데.. 이런 이유가 맞는지는 좀 더 두고 봐야겠습니다..
아,, 그리고 또 한가지 궁금한건.. 위와 같은 동일 환경에서 논블록킹 소켓으로 돌렸을경우에 MySQL DB에서 결과값 얻어오는 부분이 이상하게 작동하거든요.. 그러니까 row의 컬럼이 8개여야되는데.. 6개만 로딩되고,, 전혀 엉뚱한 값으로 세팅되어있는식으로요.. 블로킹 소켓에서는 잘되는 코드인데도 말입니다. 멀티 쓰레딩 + 논블록킹 소켓을 사용하려면 멀티쓰레딩 + 블록킹 소켓을 사용할때와 다르게 처리해야되는 부분이 있는건가요?
closed 된 소켓에 write를 하면 SIGPIPE가 발생합니다.
closed 된 소켓에 write를 하면 SIGPIPE가 발생합니다.
혹시 SIGPIPE를 ignore 하고 계신가요?
그리고 non-blocking 소켓시 이상하게 작동하는 하신다고 하셨는데..
read(or recv)에서의 return 값을 check해 보셨는지요?
[quote="vness"]closed 된 소켓에 write를 하면 SI
네,, 맞습니다. SIGPIPE 를 무시하고 있습니다.. 논블록킹에서의 read시 데이타는 체크하고 있구요..
한 클래스에서 클래스 멤버 변수로 MYSQL의 커넥션을 가지고 있고.. 그 클래스에 DB에 데이타를 저장/삽입/로드 하는 함수를 여러개 가지고 있는데요.. 커넥션이 하나라서 각각의 쓰레드에서 데이타를 가져올때 꼬이는 문제 같거든요.. 이럴때엔 mysql의 커넥션도 락/언락을 해줘야되는걸까요?
당연히 mysql connection에 lock/unlock을 해줘야 합
당연히 mysql connection에 lock/unlock을 해줘야 합니다. -_-a;
linux에서 작업하시나요? pthread를 사용하신다는 가정하에..
pthread_specific data를 사용하시면 각 thread 마다 mysql connection을
가지도록 할 수도 있을텐데요. 더 쉬운 방법도 있으려나?
앗! 그렇군요.. -_-;; freebsd, pthread입니다. 답변
앗! 그렇군요.. -_-;; freebsd, pthread입니다. 답변 감사합니다.. !!pthread_specific data는 잘모르는거라서 지금 적용하기에는 무리가 있어서 일단 MYSQL 커넥션을 여러개 가지고 있다가 사용중이지 않은 커넥션을 가져와서 사용하는식으로... 처리를 하려고 합니다..
[code:1] #include <pthread.h&
혹시 필요하시면.. 이 4개 함수를 찾아보시면 되구요..
건승하시길.. ^^;;
한가지 더 추가로 질문 좀 할게요.. -_-;; 현재 쓰려는 소켓이 정상
한가지 더 추가로 질문 좀 할게요.. -_-;; 현재 쓰려는 소켓이 정상적인 소켓인지 알수있는 방법이 있을까요?
[code:1]fd_set fds;timeval timeout;
이런식으로 되네요. return 값을 체크해서 0보다 작으면 끊어주면 되는군요..
댓글 달기