쓰래드 메모리 누수와 쓰래드 자원정리
글쓴이: newtypes / 작성시간: 토, 2007/08/25 - 11:28오전
안녕하세요
아래의 내용은 문제가 있다고 생각되는 부분입니다.
처음 실행했을 때 데몬이 동작하는데는 문제가 없습니다.
하지만 메모리를 점차적으로 갈아먹어 RSS 메모리 부분이 200M 이상까지 계속증가하다가 결국
데몬이 정지(죽지는 않네요;;;)되어버리는 현상이 발생합니다.
쓰래드 자원을 정리하지 못하여 메모리누수가 발생하는 것이라고 생각하고 있지만 쓰래드 부분은 아직 공부중이라 잘모르겠네요.
여러분들이 한번보아 주시고 지적해 주시면 참고하도록 하겠습니다.
더운날씨에 수고하시기 바랍니다.
-----------------------------------------------------------------------------------
. . . . int Queue_isOver(void) { if (((Queue_Tail+1) % Queue_MAX) == Queue_Head) { Queue_Head = Queue_Tail + 1; return 1; } return 0; } int Queue_isUnder(void) { if (Queue_Head == Queue_Tail) { return 1; } return 0; } int Add_Queue(char *data) { if (Queue_isOver()) { return 0; } Queue[Queue_Tail] = data; Queue_Tail = (Queue_Tail + 1) % Queue_MAX; return 1; } void *Del_Queue(void *sock_client_fd) { int client_fd=0; char queue_buf[512]; memset(queue_buf, 0x00, 512); memcpy((void *)&client_fd, (char *)sock_client_fd, sizeof(int)); // 클라이언트 소켓 FD 복사 while(!Queue_isUnder()) // Quere가 비어 있지 않다면 { sprintf(queue_buf,"%s",Queue[Queue_Head]); Queue_Head = (Queue_Head + 1) % Queue_MAX; // 2 / 100 = 0.02 -> "2" if(queue_buf != NULL) switch_command(queue_buf); // 적절한 명령을 수행 } close(client_fd); } void *Data_Add(void *data) { int sockfd; struct sockaddr_in clientaddr; int client_len = sizeof(clientaddr),chk=0; char buf[512], de_buf[512]; memset(buf, 0x00, 512); memset(de_buf, 0x00, 512); memcpy((void *)&sockfd, (char *)data, sizeof(int)); // 클라이언트 소켓 FD memcpy((void *)&clientaddr, (char *)data+sizeof(int), client_len); // 10진화된 ip address if (read(sockfd, buf, 512) <= 0) { chk=1; } else { sprintf(de_buf,"%s", decrypt_msg(buf)); // 메세지 암호 해제 if(sockfd > 0) Add_Queue(de_buf); } close(sockfd); } int main(int argc, char **argv) { pthread_t Q_thread, P_thread; struct sockaddr_in clientaddr, serveraddr; char th_data[256], working_sockfd[16]; pid_t pid1; int server_sockfd, client_sockfd, client_len, on=1; memset(th_data, 0x00, 256); if((pid1 = fork())!=0)//부모 프로세스 바로 종료 exit(0); setsid(); // 세션 리더로 만든다. signal(SIGPIPE, SIG_IGN); chdir("/"); umask(0); if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error : "); exit(0); } // mutex 초기화 pthread_mutex_init(&sync_mutex, NULL); pthread_cond_init(&sync_cond, NULL); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(22200); if(setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0) //소켓 재사용을 위해 perror("setsockopt error : "); if (bind(server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) { perror("bind error : "); exit(0); } if (listen(server_sockfd, 5) == -1) { perror("bind error : "); exit(0); } // Client 의 연결을 받아들인다. 새로운 Client 가 들어오면 쓰레드를 생성시킨다. // 이때 쓰레드 함수아규먼트로 Client 소켓지시자와 struct sockaddr_in 정보를 넘긴다. config_main(); //설정 파일을 읽어 들임 log_write("", 1); while(1) { client_len = sizeof(clientaddr); client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, (socklen_t *)&client_len); memcpy(th_data, (void *)&client_sockfd, sizeof(client_sockfd)); memcpy(working_sockfd, (void *)&client_sockfd, sizeof(client_sockfd)); memcpy(th_data+sizeof(client_sockfd), (void *)&clientaddr, client_len); if(client_sockfd > 0) { if (pthread_create(&Q_thread, NULL, Data_Add, (void *)th_data) == -1) { perror("Command add queue messages thread create error\n"); } } if(!Queue_isUnder()) { // FD 뮤덱스 락 pthread_mutex_lock(&sync_mutex); if (pthread_create(&P_thread, NULL, Del_Queue, (void *)working_sockfd) == -1) { perror("Command Running Thread Create Error\n"); } pthread_detach(P_thread); pthread_cond_signal(&sync_cond); // pthread_cond_wait(&sync_cond, &sync_mutex); pthread_mutex_unlock(&sync_mutex); } } exit(0); }
Forums:
댓글 달기