251009

lililllilillll·2025년 10월 9일

개발 일지

목록 보기
319/350

✅ 한 것들


  • 윤성우의 열혈 TCP/IP 소켓 프로그래밍


📖 윤성우의 열혈 TCP/IP 소켓 프로그래밍


Chapter 10 멀티프로세스 기반의 서버구현

10-1 프로세스의 이해와 활용

전체적 서비스 제공 시간이 조금 늦어져도 모든 클라에게 동시 서비스 제공이 좋다

  • 멀티프로세스 기반 서버 : 다수의 프로세스를 생성
  • 멀티플렉싱 기반 서버 : 입출력 대상을 묶어서 관리
  • 멀티쓰레딩 기반 서버 : 클라 수만큼 쓰레드 생성

프로세스

  • 메로리 공간을 차지한 상태에서 실행중인 프로그램
  • 운영체제로부터 ID 부여받는다

fork()

  • 호출한 프로세스의 복사본 생성
  • fork()를 호출한 프로세스를 복사하는 것
  • 두 프로세스 모두 fork 호출 이후 문장을 실행하게 된다
    • 부모 프로세스의 fork 반환 값 : 자식 프로세스 ID
    • 자식 프로세스의 fork 반환 값 : 0
int gval = 10;
int main(int argc, char *argv[])
{
	pid_t pid;
	int lval=20;
	gval++, lval+=5;

	pid=fork();
	if(pid==0) // if child
	{
		gval+=2, lval+=2;
		printf("Child Proc: [%d, %d] \n", gval, lval);
	}
	else // if parent
	{
		gval-=2, lval-=2;
		printf("Parent Proc: [%d, %d] \n", gval, lval);
	}
	return 0;
}

10-2 프로세스 & 좀비 프로세스

ps au로 프로세스 확인 가능

fork로 생성한 자식 프로세스가 종료되는 상황

  • 인자를 전달하면서 exit를 호출하는 경우
  • main 함수에서 return문을 실행하면서 값을 반환하는 경우

좀비 프로세스

  • 할 일 다하고도 안 사라짐
  • 부모 프로세스에게 exit 함수 인자 값이나 return문의 반환 값 전달돼야 좀비 죽일 수 있다

좀비 프로세스의 생성 이유

int main(int argc, char *argv[])
{
	pid_t pid=fork();

	if(pid==0) // if child
	{
		puts("Hi, I am child process");
		puts("End child process");
	}
	else
	{
		printf("Child Process ID: %d \n", pid);
		sleep(30);
		puts("End parent process");
	}
	return 0;
}

  • child가 return돼서 끝나도, parent가 return해야 child의 자원이 반환된다.
    • wait()를 호출하지 않고 return까지 갔다면 커널이 고아 프로세스에게 wait() 호출

좀비 프로세스의 소멸1: wait 함수의 사용

wait() 함수

  • wait()가 호출됐을 때, 이미 종료된 자식 프로세스가 있다면, 종료 당시 전달 값이 인자로 넣은 주소 변수에 저장된다
  • 이 변수에 들어있는 다른 값을 매크로 함수로 분리
    • WIFEXITED : 자식 프로세스가 정상 종료했다면 true
    • WEXITSTATUS : 자식 프로세스의 전달 값
int main(int argc, char *argv[])
{
	int status;
	pid_t pid=fork();

	if(pid==0)
	{
		return 3;
	}
	else
	{
		printf("Child PID: %d \n", pid);
		pid=fork();
		if(pid==0)
		{
			exit(7);
		}
		else
		{
			printf("Child PID: %d \n", pid);
			wait(&status);
			if(WIFEXITED(status))
				printf("Child send one: %d \n", WEXITSTATUS(status));

			wait(&status);
			if(WIFEXITED(status))
				printf("Child send two: %d \n", WEXITSTATUS(status));
			sleep(30);
		}
	}
	return 0;
}

  • 실행하면 각 프로세스의 PID와 return 값이 출력된다
  • wait()는 프로세스 한 개만 소멸시킨다
  • 호출된 시점에서 종료된 자식 프로세스가 없으면 종료될 때까지 Blocking된다

좀비 프로세스의 소멸2: waitpid 함수의 사용

waitpid()는 좀비 프로세스 생성 막으면서도 블로킹 문제 해결한다

int main(int argc, char *argv[])
{
	int status;
	pid_t pid=fork();

	if(pid==0)
	{
		sleep(15);
		return 24;
	}
	else
	{
		while(!waitpid(-1, &status, WNOHANG))
		{
			sleep(3);
			puts("sleep 3sec.");
		}

		if(WIFEXITED(status))
			printf("Child send %d \n", WEXITSTATUS(status));
	}
	return 0;
}
  • 자식 프로세스는 15초 동안 기다린 다음 종료된다
  • waitpid()는 블로킹을 안 하기 때문에, 3초 마다 문구를 출력한다


profile
너 정말 **핵심**을 찔렀어

0개의 댓글