쓰래드 메모리 누수와 쓰래드 자원정리
글쓴이: 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:


댓글 달기