쓰래드 메모리 누수와 쓰래드 자원정리

newtypes의 이미지

안녕하세요

아래의 내용은 문제가 있다고 생각되는 부분입니다.
처음 실행했을 때 데몬이 동작하는데는 문제가 없습니다.
하지만 메모리를 점차적으로 갈아먹어 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);
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.