Inter-Process Communication (IPC)
- Processes within a system may be independent or cooperating
- Independent process cannot affect or be affected by the execution of another process
- Cooperating process can affect or be affected by other processes, including sharing data
- Reasons for cooperating processes:
- Information sharing
- Computation speedup
- Modularity
- Convenience
- Cooperating processes require an IPC mechanism that will allow them to exchange data
- Two fundamental models of IPC:
- Message passing & Shared memory
Two Fundamental IPC Models (1/2)
1) Message-passing model: Communication takes place by means of messages exchanged between the cooperating processes
협력 프로세스 간에 교환되는 메시지를 통해 의사소통이 이루어집니다
- Useful in a distributed environment
- Typically implemented using system calls, thus requiring the more time-consuming task of kernel intervention
일반적으로 시스템 호출을 사용하여 구현되므로 커널 개입이라는 시간 소모적인 작업이 필요합니다
- Two key operations: send(message) & receive(message)
Message Passing
- Producer-consumer becomes trivial
- Processes need to:
1) Establish a communication link between them
2) Exchange messages via send/receive methods
위는 유저, 아래는 커널 영역임.
Two Fundamental IPC Models (2/2)
- Shared-memory model: Cooperating processes establish a region of shared memory and then they can exchange information by reading and writing data in the shared areas
- Typically, a shared memory region resides in the address space of the process creating the shared-memory segment
- Faster than message passing because system calls are required only to establish shared memory regions.
공유 메모리 영역을 설정하는 데에만 시스템 호출이 필요하기 때문에 메시지 전달보다 빠릅니다.
- Once established, all accesses are treated as routine memory accesses, and no assistance from kernel is required
- The communication here is under the control of the users’ processes, not under the OS’s control
- Major issue is how to provide mechanism that will allow the user processes to synchronize their actions when they access shared memory
주요 문제는 사용자 프로세스가 공유 메모리에 액세스할 때 동작을 동기화할 수 있는 메커니즘을 제공하는 방법입니다
Shared Memory
-
POSIX Shared Memory
-
Process first creates shared memory segment
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
- Also used to open an existing segment to share it
-
Set the size of the segment
ftruncate(shm_fd, 4096);
-
Map the shared memory segment to a specific memory region
ptr = mmap(0, size, PROT_WRITE, MAP_SHARED, shm_fd, 0);
-
Now the process could write to the shared memory
sprintf(ptr, "Writing to shared memory");
-
IPC POSIX Producer
What about IPC in Linux?
- Linux provides a rich environment for processes to communicate with each other
- A mechanism for notifying a process about a particular event occurrence
- Several mechanisms for passing data among processes
- Shared memory
- Message queue (= message passing)
- Pipes
- A set of networking facilities
Signals
- A IPC mechanism to notify a process of a particular event
- Can be synchronous (e.g., illegal memory access) or asynchronous (e.g., killed)
- Can be thought as a software interrupt
- Signal is generated by particular events
- Signal is delivered to the process
- A signal handler processes the signal
- Every signal has a default handler that kernel runs when handling signal
- User-defined signal handler can override the default
Signal Handling
- A process can define a signal handler for a signal
#include <signal.h>
void signal_handler(int signal_number) {
printf("%d signaled!\n", signal_number);
}
struct sigaction sa = {
.sa_handler = signal_handler,
.sa_flags = 0,
}, old_sa;
sigaction(SIGALRM, &sa, &old_sa);
- A process can send a signal to other process
- int kill(pid_t pid, int sig);
- The signal handler is invoked on the target process
$ man 7 signal
Pipes
- A pipe acts as a conduit allowing two processes to communicate
- Pipes can be accessed using ordinary read() and write() system calls as UNIX treats a pipe as a special type of files
- e.g., The output of one process can be directed into the input of another process by using a pipe (I/O redirection)
- Two common types of pipes used on both UNIX/Linux and Windows systems
- Ordinary pipe VS. Named pipe
- Ordinary pipes: allowing only one-way communication (= unidirectional) and requiring parent-child relationship between communicating processes
- Producer writes to one end (the write-end of the pipe)
- Consumer reads from the other end (the read-end of the pipe)
- Ordinary pipes are therefore unidirectional
- pipe(int fd[])
Ordinary pipe in Linux
Pipes
- Named pipes:
- More powerful than ordinary pipes
- Communication is bidirectional
- No parent-child relationship is necessary between the communicating processes
- Several processes can use the named pipe for communication
- Named pipes stay alive even after process terminates
Network Structure
- Internally, networking in the Linux kernel is implemented by 3 components:
- The socket interface
- Protocol stack (TCP/IP protocol suite)
- The IP protocol implements routing between different hosts anywhere on the network
- On top of the IP protocol are built the UDP or TCP protocols
- Network-device drivers
- Ethernet, WiFi, Bluetooth, etc.
UDP vs. TCP
- UDP (User Datagram Protocol)
- Unreliable
- Since there are no guarantees of delivery, some packets may become lost
- Packets may also be received out-of-order
- Fast transmission
- TCP (Transmission Control Protocol)
- Reliable & in-order
- Whenever host sends packet, the receiver must send an acknowledgement packet (ACK). If ACK is not received before a timer expires, sender will resend.
- Sequence numbers in packets allow receiver to sort packets in order and notice missing packets.
- Slower speed than UDP
보내는 사람 입장에선 data가 제대로 도착하든 그렇지 않든간에, ack가 오지 않으면 resend 하네..
Communication in Client-Server Systems
- Client-Server Computing Systems
- A specialized distributed system in which server systems satisfy requests generated by clients
- Most network process communications follow a client-server model
- A process on one computer acts as a server, and a process on another computer acts as a client
- Two strategies for communication in client-server systems
- Sockets
- Remote Procedure Calls(RPC)
Sockets
- A socket is defined as an endpoint for communication
- A pair of processes communicating over a network employs(이용하다) a pair of sockets (one for each process)
- Each socket is associated with an unique combination of IP address and port
- The socket 161.25.19.8:1625 refers to port 1625 on host 161.25.19.8
- A server opens up a specified port(16비트 미만) for listening & waits for incoming client requests.
- Once a request is received, the server accepts a connection from the client socket to complete the connection
- All connections must be unique, meaning that they consist of a unique pair of sockets!
- All ports below 1024 are well known, used for standard services
- Servers implementing specific services listen to well-known ports (e.g., Web/HTTP server: port 80, FTP server: port 21, SSH server: port 22)
- A client initiating a request for a connection is assigned a port by its OS.
- This local port has some arbitrary number greater than 1024
서버는 1024 미만 클라이언트는 서버가 port를 지정해주고 1024이상이구나 별로 중요하지 않은듯
Socket Programming in C/C++
- Unix-like OS tries to interact with devices, file, and networks in a uniform fashion
- OS treats them all as part of the file system
- Socket system calls are used for inter-process communication over a network
- 3 steps (connect, send/receive data, terminate), similar to the basic file I/O (open, read/write, close)
- Berkeley Sockets serve to implement this abstraction for network communication
Berkeley Sockets Example (TCP Server)
socket()
- The socket() system call has 3 arguments: Domain, Communication types, Protocol
- Domain of communication
- The Internet domain: AF_INET or PF_INET for IPv4, AF_INET6 or PF_INET6 for IPv6
- The UNIX domain: AF_UNIX or PF_UNIX or AF_LOCAL or PF_LOCAL
- Types of communication
- SOCK_STREAM : TCP/IP
- SOCK_DGRAM : UDP/IP
- A socket provides an integer identifier through which a network communication is going to take place. The newly created socket is analogous to a telephone that has not yet been used to place a call; the socket identifier has not yet been used to connect to anything
bind()
- A server will typically bind the socket, defining the IP and port on which it will listen for connection
서버는 일반적으로 소켓을 바인딩하여 연결을 수신할 IP와 포트를 정의합니다
- The struct sockaddr_in holds information about how the socket will be used
listen()
- After binding, a server may call listen() to await communication
int listen(int sockfd, int backlog)
-> The 2nd parameter, backlog, describes how many connections can be queued (5 in the example below) while the server is handling another communication. An error value (-1) will be returned to additional clients trying to connect.
accept()
- Once a server has received an incoming connect attempt, it can accept the connection
- accept() returns a second socket on which data will be transmitted. This allows the original socket to continue to listen for additional connections
int accept(int sockfd, struct sockaddr addr, socklen_t addrlen)
recv_addr로부터 클라이언트 정보를 받아온다!
connect()
- A client performs a step similar to binding, but instead of listening, it actively makes a call, establishing a connection
- The connect() is used to call the server in an attempt to establish a connection
binding은 os가 알아서 해주므로 필요없다.
send() & receive()
- After a connection has been established between the client and server, data can be transmitted and received
- The send() system call takes 4 arguments: Socket identifier, Address pointing to data, Number of bytes to send, Flag setting
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
- The recv() also takes 4 arguments: Socket identifier, Address pointing to data, Max Number of bytes to receive, Flag setting
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
- Both the server and client can execute send() and recv()
- The send() and recv() functions are similar to the fread() and fwrite() functions in that the arguments define an address and a number of bytes, rather than the type of data at the given address
argument가 주어진 주소의 데이터 유형이 아니라 주소와 바이트 수를 정의한다는 점에서 유사하다
Example Codes for send() & receive()
close()
- Once communication is finished, both the server and client should close their respective sockets
- A close() system call initiates a series of operations within the OS to terminate the connection
시스템 호출이 종료되면 OS 내에서 일련의 작업이 시작되어 연결이 종료됩니다
- Thus, the socket may still appear in a netstat program listing for several seconds, until the OS has finished the close
따라서, OS가 닫기를 완료할 때까지 소켓은 netstat 프로그램 목록에 몇 초 동안 계속 표시될 수 있습니다
Server Example
Client Example
Sockets versus RPCs
- Communication using sockets (although common and efficient) is considered a low-level form of communication between distributed processes
- Why? … because sockets allow only an unstructured stream of bytes to be exchanged between the communicating threads. It is the responsibility of the client or server application to impose a structure on the data
소켓은 통신하는 스레드 간에 구조화되지 않은 바이트 스트림만 교환할 수 있기 때문입니다.
- Now, lets look a higher-level method of communication: Remote procedure calls (RPCs)
- One of the most common forms of remote service
- A way to abstract procedure calls between processes on networked systems
- Not only useful for client-server computing, but Android also uses remote procedures as a form of IPC(Inter-process Communication) between processes running on the same system
Remote Procedure Calls
Remote Procedure Calls (RPCs)
- The semantics of RPCs allows a client(= caller) to invoke a procedure on a remote host(= callee/server) as it would invoke a procedure locally
- The RPC system hides the details that allow communication to take place by providing stubs on the server / client sides
RPC 시스템은 서버/클라이언트 측에 스텁을 제공하여 통신을 수행할 수 있도록 하는 세부 정보를 숨깁니다
- Stubs are proxy objects that abstracts the actual procedure on the server side
스텁은 서버 측의 실제 프로시저를 추상화하는 프록시 개체입니다
- The Client-side stub locates(위치를 알아내다) the server and marshalls the parameters
- Packaging parameters into a form for transmission on network
- The server-side stub receives this message, unpacks the marshalled parameters (unmarshalling), and performs the procedure on the server
marshalling -> parameter 값을 하나의 패킷 형태로 만드는 과정 (pack과 유사)