Web server
- 서버의 network socket이 read() syscall을 보내면 일단 기다린 뒤에, kernel이 네트워크로부터 arriving packet을 받아오고, 이는 서버에 전달됨. 반대로 write()할 때는 별도의 wait는 없음.
- 하지만 어느 경우든 read와 write는 kernel-buffered임.
Communication Between Processes
- why? shared task
- "process"는 inter-process communication을 어렵게 하도록 만들어져 있다. 서로 정보를 interfere/steal하지 못하게 되어 있음.
- 따라서 이러한 보안에 "구멍"을 내야함 -> IPC(Inter-Process Communication)
- How?
- 가장 간단하게는 file을 사용하면 된다. 하지만 non-persistent한 경우에는 file에 write, read를 반복하는 것은 very expensive하다.
- 혹은 엄격하게 구분되어 있던 메모리 영역의 일부를 share할 수 있음.
- kernel의 도움을 받아, file이 아닌 in-memory queue를 이용할 수 있다. file과 동일한 인터페이스를 가지고 있으며, 매우 효율적이다.
POSIX or Unix PIPE
- pipe는 위에서 말한 in-memory queue의 일종이다.
- 만약 producer가 가득찬 버퍼에 쓰려고 한다면, block한다(put sleep until space). 만약 consumer가 텅빈 버퍼를 읽으려고 한다면, block한다(put sleep until data)
int pipe(int fileds[2])
: 2개의 새로운 file descriptor를 할당함.fileds[1]
를 통해 pipe에 쓰고,fileds[0]
를 통해 pipe로부터 읽는다.- pipe() 후 단순히 fork()를 하게 되면 두 개의 프로세스가 read end, write end에 모두 연결되어 있다. 그래서 보통은 쓰는 쪽(e.g. 부모 프로세스)의 read end를 닫고, 읽는 쪽(e.g. 자식 프로세스)의 write end를 닫아주는 식으로 사용한다.
- 모든 write end가 닫히게 되면 EOF만 나오고, 모든 read end가 닫히게 되면 EPIPE 에러가 나온다.
Protocol
- communication에는 어떻게 소통할지에 대한 합의사항인 프로토콜이 필요하다. 프로토콜에는 syntax와 semantics 등이 포함된다.
Socket
network connection: bidirectional stream of bytes between two processes(on possibly different machines)
file I/O와 유사한 방식으로 socket을 사용한다. socket은 abstraction for one endpoint of network connection으로서, IPC를 위한 메커니즘 중 하나다.
socket은 마치 file descriptor를 가진 파일처럼 생겼고, 2개의 queue를 가지고 있다. write는 output queue에, read는 input queue에서 작동한다. 그러나 파일의
lseek
등은 작동하지 않는다.Assumptions
reliable: file에서처럼 socket에 쓴 내용이 반대쪽에서 그대로 읽어진다고 가정한다.
in order(sequential stream): 쓴 순서대로 읽게 된다고 가정한다.
이미 writing이 이루어져서 읽기만 하면 된다고 가정한다.
Socket Creation
- file systems provide a collection of permanent objects in a structured name space*
- pipe: one-way communication between processes on same machine
- single queue이며 unidirectional하고, descriptor가 부모 프로세스에서 자식 프로세스로 상속되는 구조로 연결된다.
- sockets: two-way communication between processes on same or different machine
- two queues
- no common ancestor
- TCP/IP를 통해 소통하기 위해서는 server가 server socket을 만들어야 한다. 이 서버 소켓은 read나 write하지 않는다. server socket은 listen()하고 있다가, client socket에서 request가 오면 accept()를 통해 "특정 client를 위한 새로운 socket"을 만든다.
- 이렇게 구축되는 connection은 5-Tuple로 유니크하게 구별된다. 흔히 client port는 randomly 할당되는 반면, server port는 0-1023 범위 내에서 잘 알려져 있다(80은 웹, 443은 secure web, 25는 sendmail 등).
- 서버에서는 connection socket을 만든 뒤에 fork()를 통해 자식 프로세스가 connection socket만 가지고 클라이언트와 소통 후 소켓을 닫도록 하고, 부모프로세스는 connection socket을 닫고 server socket만 가진 채 새로운 connection을 기다린다.
- fork() 대신 pthread_create를 통해 여러 스레드를 사용하면 concurrency를 더 잘 대응할 수 있지만, 너무 많은 스레드가 생기게 되면 crash할 수 있다. 따라서 thread pool을 통해 제한된 수의 스레드만을 사용하게 한다.
'컴퓨터 > 운영체제' 카테고리의 다른 글
[UCB CS162 OS] Lec07 Synchronization(2) (0) | 2024.01.12 |
---|---|
[UCB CS162 OS] Lec06 Synchronization(1) (0) | 2024.01.11 |
[UCB CS162 OS] Lec04 Files & I/O (0) | 2024.01.05 |
[UCB CS162 OS] Lec03 Threads (0) | 2024.01.04 |
댓글