fork()는 새로운 자식프로세스를 실행시키기 위해서 사용하며, 다수의 클라이언트를 동시에 처리하기 위해서 입출력다중화(:12)와 함께 가장 널리 사용되는 방식이다.
이 방식의 단점이라면 fork()로 새로운 프로세스를 생성시키는 자체에 많은 비용이 들어간다는 점이 될 것이다. 이 문제를 해결하기 위해서 적당한 수만큼 프로세스를 미리 할당시켜 놓고, 새로운 연결이 들어오면 할당된 프로세스에 소켓을 전달해주는 prefork방식을 사용하기도 한다. 일종의 프로세스 풀을 만들어서 활용 하는 것으로 볼 수 있다. 이 문서는 prefork 에 대해서 소개한다.
다음과 같은 정보들을 가지고 있다면 문서의 접근이 쉬울 것이다.
prefork 구현의 핵심은 accept 함수 호출 후 만들어진 '소켓 지정 번호'를 어떻게 이미 만들어져 있는 자식 프로세스에 전달하느냐에 있다. 다행히 이에 대한 해법은 나와 있긴 한데, 해법 자체가 좀 마법적이다.
소켓 전달은 sendmsg(:2) 함수로 이루어진다. sendmsg 함수는 msghdr 구조체로 데이터를 전달하는데, msghdr 구조체에 전달할 소켓 지정 번호 정보를 포함한 제어 정보를 함께 넘기는 방식으로 이루어 진다. 다음은 소켓 전달을 위해서 사용하는 함수인 write_fd 이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
fork(2)방식에서 소켓전달이 성공적으로 이루어지는걸 확인했다. 이제 exec(2)에서도 가능한지 확인해 보려 한다. 위의 프로그램을 약간 수정해서 클라이언트의 연결을 accept하고 prefork를 하는 socketmain.c 프로그램과 prefork되어서 데이터를 처리하는 prefork.c라는 프로그램을 만들었다.
socketmain.c는 위의 fork 버젼에서 아래의 라인만 수정했다.
소개
소켓 전달
테스트에 사용할 echo 서버
exec 응용
참고문헌
Recent Posts
Archive Posts
Tags