소켓 통신에서 서버 좀비 및 프로세스 처리 문제

boardholic의 이미지

기존 소스를 약간 수정하여
간단한 게임서버로 사용중 시간이 갈수록(서버 접속횟수가 늘어날수록)
이상하게 메인 프로세스 외에 기타 프로세스들이 생성이 되어있습니다.
S, Ss등등 Z(좀비)는 아닌것 같은데 무슨 문제인지 잘 모르겠네요.
아래 소스를 한번 봐주시기 바랍니다.

#include 함수들 생략 ...
 
//함수선언
void sigchld_handle(int num);
int wait_child(int pid);
void insert_chld (int childid);
int init_server(short port);
int reinit_server(short port);
int get_connection(short port);
 
#define MAXPIDSIZE 1000
 
static int chld_pid[MAXPIDSIZE];//자식프로세스 아이디 저장
static int listensockd; //서버소켓
int receivePktSize;//받은패킷 사이즈
 
int main()
{
	int result_sock;
	int childid;
	int status;
	int i;
	char tmpBuf;
	int ret;
 
	struct sigaction act, oact;
 
	Log("server start try");
	if ((childid=fork()) == -1) {
		perror("first fork failed");	
		return;
	}
	else if (childid != 0)
		return;	
 
/*	 act.sa_handler = sigchld_handle; */
/*	 sigemptyset (&act.sa_mask); */
/*	 act.sa_flags = 0; */
/*	 act.sa_flags |= SA_RESTART; */
/*	 sigaction (SIGCHLD, &act, &oact); */
 
	signal(SIGCHLD, SIG_IGN);
	memset (chld_pid, -1, sizeof(chld_pid));
 
/*	 init_log(); */	
 
	init_server(10002);
	Log("server started");
 
	while(1) {
		//접속한 클라이언트 소켓을 얻어온다.		
		if ((result_sock=get_connection(10002))==-1) {
			Log("Connection Failed");
			if (reinit_server(10002) == -1)
				Log("Reinit Failed");
			continue;
		}						
 
		if ((childid=fork())==-1)
			Log("Server Fork Failed"); //에러처리할것
		else if (childid == 0) { //자식프로세스								
			Log("child (%d) started", getpid());
 
			close(listensockd);//서버소켓 종료
			setsid ();		//데몬만들기		
 
			//표준입출력 닫기
			close(0);
			close(1);
			close(2);
 
			//데이터 송수신 처리			
			child_proc(result_sock);
			break;
		}
		else { //부모프로세스							
			insert_chld (childid);
			close(result_sock);//클라이언트소켓 종료
		}
	}
 
	close(result_sock);
	Log2("Connection Closed");
}

signal(SIGCHLD, SIG_IGN)에서 좀비를 처리하는것같습니다.
전체적으로 문제가 될만한 곳이 있는지 어떤 부분에 의해 프로세스들이 종료가
안되고 생성되어 있는지 고수님들의 조언 부탁합니다.

caihan의 이미지

맞는 지는 모르겠지만 waitpid 함수는 PID를 직접선택하여 기다리는 함수 입니다.
여기서 바로 종료 순서 문제가 나올 수 있겠네요...
예를 들어 5개의 프로세스를 만들었고 waitpid 함수를 사용한다고 한다면
처음 어떤 한개가 종료되기를 지정해 줘야 할것 입니다.
하지만 5개중 어떤게 먼저 종료 될지 알 수 없는 문제 입니다.
1번 프로세스를 wait 하고 있는데 3번 프로세스가 종료되 버리면
3번 프로세스는 바로 좀비가 되고 1번 프로세스를 계속 블럭킹 하면서 기달리는 현상이 발생할 것 같습니다.
waitpid 함수 부분을 wait 함수로 바꿔보시고 테스트를 해보시면 어떨까요.
wait 함수는 생성된 자식 프로세스들 중 어느하나가 종료되면 바로 리턴 됩니다.
물록 블럭킹 모드로 작동 됩니다.
아주쪼록 문제해결이 잘 되시길 바랍니다.

caihan의 이미지

아 그리고 지금 보니 시그널을 받아서 종료 처리를 하고 계신데요.
이건 좋은 방법이 아닌듯 합니다.
프로세스가 어떠한 에러 때문에 종료될지 알 수 없기 때문에
( 종료된 파이프로 메시지를 보냈다던지...메모리 요류로 바로 종료되는 현상 등등 )
시그널로 처리 하는건 안정성에 문제가 되지 않을 까 십습니다.
이게 바로 signal-safe 라는 문제인데...
wait 함수를 지역함수로 빼서 처리를 하신듯 한데...제가 알기론
이 방법또한 그렇게 좋은 방법이 아닌걸로 알고 있습니다..

boardholic의 이미지

답변 감사합니다^^

기존 sinal처리 함수들은 사용 안되고 있는 것들입니다.

signal(SIGCHLD, SIG_IGN)이 함수로 좀비처리는 될거같은데
원인을 잘 모르겠네요.

현재 실행중인 프로세스들이 존재할때의 상황을 제가 잘못 본거인지, 오랫동안 사라지지 않는걸
보면 그건 아닌것 같은데요. 좀더 확인해 보겠습니다.

나에게 있어 한계란 없다.
무한한 꿈을향해 나아간다.

caihan의 이미지

아마도 제 예상이 맞을 것 같습니다. 저도 예전에 같은 문제로 고민한 적이 있었는데
wait 함수로 해결했었습니다.
wait 함수를 사용했음에도 좀비가 생긴다는 얘기는...
정확합니다. 좀비가 된 프로세스가 wait 함수에서 인식하지 못한 겁니다.
그리고 생성된 프로세스가 많으면 wait 를 여러번 돌려 주셔야 합니다.
wait 함수의 에러메시지를 보고 더이상 자식 프로세스가 있는지 없는지 여부도 알 수 있습니다.
그리고 프로세스가 종료 될때는 SIGCHLD 만 오는 것이 아닙니다. 그러므로 SIGCHLD 만을 이용하여
종료하는 것은 않됩니다. 정확히 에러마다 처리를 해주는 것이 바람직 합니다.
해보실 사항은 프로세스를 만드는 부모 프로세스에

int st;
 
while( 1 ) {
 
wait( &st );
 
}

해보세요. 아마도 자신이 만든 모든 자식 프로세스가 제대로 종료될 것입니다.

댓글 달기

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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 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>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 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>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 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>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.