⚠️ 해당 포스팅은 인프런 공룡책 강의를 듣고 개인적으로 정리하는 글입니다. 정확하지 않은 정보가 있을 수 있으니 주의를 요합니다.
Chapter 3 Process (2)
wait()
시스템 콜을 진행하며 소비자는 이를 소비한다.wait()
시스템 콜을 진행하며 생성자는 버퍼를 채운다.// IPC in Shared-Memory Systems
#define BUFFER_SIZE 10
typedef struct {
. . .
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
item next_produced;
while(true) {
/* produce an item in next_produced */
while(((in + 1) % BUFFER_SIZE) == out);
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
}
item next_consumed;
while(true) {
while(in == out); /* do nothing */
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
/* consume the item in next_consumed */
}
send(message)
, receive(message)
message next_produced;
while(true) {
/* produce an item in next_produced */
send(next_produced);
}
message next_consumed;
while(true) {
receive(next_consumed);
/* consume the item in next_consumed */
/* in = out 이런 것을 O/S가 처리해주어 편리하다. */
}
send(P, message)
, receive(Q, message)
send(P, port)
, receive(Q, port)
// Producer
int main() {
const int SIZE = 4096;
const char *name = "OS";
const char *message_0 = "Hello, ";
const char *message_1 = "Shared Memory!\n";
int shm_fd; // the file descriptor of shared memory
char *ptr; // pointer to shared memory
/* create the shared memory object */
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory */
ftruncate(shm_fd, SIZE); // 4096 byte 씩 읽고 쓰기
/* map the shared memory object */
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
/* write to the shared memory */
sprintf(ptr, "%s", message_0);
ptr += strlen(message_0);
sprintf(ptr, "%s", message_1);
ptr += strlen(message_1);
return 0;
}
// Consumer
int main() {
const int SIZE = 4096;
const char *name = "OS";
int shm_fd; // the file descriptor of shared memory
char *ptr; // pointer to shared memory
/* create the shared memory object */
shm_fd = shm_open(name, O_RDONLY, 0666);
/* map the shared memory object */
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
/* read from the shared memory object */
printf("%s", (char *)ptr);
/* remove the shared memory */
shm_unlink(name);
return 0;
/* 첫 번째 실행 -> Hello, Shared Memory
두 번째 실행 -> Segmintation Fault (포인트가 뒤로 밀려 쓰레기값 출력) */
}
(양방향 통신을 사용할 때는 서로 통신을 진행하다가 충돌이 일어날 수 있는 가능성 있음)
(half-duplex(무전기), full-duplex(전화기) 로 대입하여 생각하면 편리)
fd[0]
의 경우 읽기 전용, fd[1]
의 경우 쓰기 전용으로 구성한다.
public class DateServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(6013);
/* Now listen for connections */
while (true) {
Socket client = server.accept();
PrintWriter pout = new PrintWriter(client.getOutputStream(), true);
/* write the Date to the socket */
pout.println(new java.util.Date().toString());
/* close the socket and resume listening for connections */
client.close();
}
}
}
public class DateClient {
public static void main(String[] args) throws Exception {
/* make connection to server socket */
Socket socket = new Socket("127.0.0.1", 6013);
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
/* read date from the socket */
String line = null;
while ((line = br.readLine()) != null)
System.out.println(line);
/* close the socket connections */
socket.close();
}
}
만약 프로시저를 호출하는데, 한 컴퓨터는 64bit에 little-endian 방식을 사용하고, 다른 컴퓨터는 32bit에 big-endian 방식을 사용한다면, 어떻게 데이터를 주고받을 것인지 생각해야 한다.