[운영체제] semaphore - pingpong game 만들기
semaphore를 이용한 pingpong game을 만들어보았다.
위의 스크린샷은 ping-pong 게임을 구현한 결과이다. 처음에는 server.c를 컴파일한 다음 server를 먼저 실행하고, 그 다음에 client를 실행한다. Server를 먼저 실행해야 하므로 처음 실행 시에 server에만 your turn!이라는 문구가 먼저 뜨고, client에는 아무런 문구도 뜨지 않는다.
Server에서 먼저 입력을 한 다음에 엔터를 치면, client에서 입력을 감지해 your turn! 메시지를 출력하게 된다. 이 동작을 번갈아가면서 하게 되며 각각 5턴을 하면 게임이 끝나는 것을 볼 수 있다. 여기서 Server는 ping을, Client는 pong을 입력해야 하며 이외의 답이 입력되었을 경우 점수가 20점씩 감점되는 모습을 볼 수 있다.
Server 측면
⓵ semaphore 정의
우선 초기화를 시키기 위해서, semaphore 헤더를 include를 시켜준 다음, 세마포어를 생성했다. 이것을 생성하여, 각각 client와 server가 통신할 때 wait과 post를 이용할 게 될 것이다. 이렇게 해야지 원하지 않는 값, 또는 client와 server가 서로 경쟁을 하지 않게 하기 위해서 필요한 방법이다.
생성이 잘 되었다면 아무런 메시지를 출력하지 않지만, 생성이 되지 않았을 경우 에러를 띄우며 종료를 하게 된다. 실행시에는 잘 생성이 되었기 때문에 아무런 에러 문구가 나오지 않았다.
⓶ 파일 입출력, 처음 동작인지 아닌지 판별
파일 입출력을 이용해서 읽어오고, 쓰는 동작을 통해서 플래그처럼 사용하는 방식을 사용했다. 이 방식을 사용하기 위해서 파일을 읽고 쓸 수 있도록 먼저 open을 한다. 예제에서는 읽기, 쓰기 등 둘 중에 하나의 방식만을 채택했지만 이 server와 client 파일에서는 읽고 쓰는 동작을 모두 허용해야 하므로 읽기&쓰기 허용을 하는 옵션인 O_RDWR를 사용하여 파일을 열었다.
그리고 나서, first라는 변수를 선언해주는데 이 변수는 Server와 같은 경우에 처음에 먼저 시작해야 하므로, 처음에 먼저 처리해주기 위해서 처음인 경우(first == 0)는 while 문을 동작하지 않고 바로 문자를 받고 처리하는 로직으로 간다. 이외에 처음이 아닌 경우(first != 0)에는 client가 동작한 것을 판단하고 동작해야 하므로 while문 안에서 동작하다가, client가 입력된 것을 확인하면 그제서야 입력을 받도록 하기 위해 사용하는 것이다.
while문을 보면, read를 사용하여, file_test에 있는 것을 버퍼 크기만큼 읽어와서, 이 읽어온 것이 xpong\n 즉, client가 입력한 것이라면 while문을 break하면서 다음 Server에 대한 처리로 넘어가는 것이고, 아니라면 계속 sleep(1)을 하면서 client의 입력을 기다리고 있게 된다.
⓷ 세마포어 이용 및 값 입력 후 처리
이전에 생성했던 세마포어로, wait-post를 이용해 안에 있는 것들이 처리되기 전까지는 넘어갈 수 없도록 한다. 이렇게 하면 race condition을 피할 수 있게 된다.
이제 your turn! 이라는 메세지가 이전의 조건을 충족시켜(client 또는 server에서 입력된 정보를 받아서 자신이 입력될 차례라는 것을 알았을 경우) 입력을 받으면 된다. Fgets로 입력을 받고, 이 입력이 ping(Server일경우)과 같다면 그냥 넘어가고 다음 루프로 넘어가면 되지만, 입력이 ping이 아니라면 wrong! 에 대한 메시지를 띄우며 score를 20점 감점시킨다. 위의 코드가 이를 의도한 코드이다.
⓸ 파일 입출력으로 플래그 기재
Server에 대한 처리(무언가를 입력했을 때)를 마치면, 여기서 동작을 처리했다고 알려줄 수 있는 것이 있어야 한다. 이 경우 file_test에 sign 즉, server와 같은 경우는 oping client는 xpong으로 설정했으며, 이것을 write를 이용하여 file에 써준다. 이 동작까지 안전하게 다 마쳤다면, post를 하여 이에 대한 정보를 보냄으로써 제어를 client로 넘긴다. 이렇게 write한 플래그는 client에서 읽어오고, server에서 처리했다는 사실을 알게 되므로 client에 대한 처리를 하여 서로서로 순서대로 동작을 반복하게 되는 것을 볼 수 있다.
이렇게 마찬가지로 client도 읽어오는 플래그 조건을 oping에서 xpong으로 바꿔주고, 첫번째 처리(Server에만 있는) 부분 등 조건들을 일부 수정하고 나머지는 server와 client가 매우 유사한 코드를 가졌다. 위의 설명으로 client 코드의 설명까지 충족하기 때문에 client에 대해서는 따로 기재하지 않았다.
* 본 게시글은 개인이 생각한 코드입니다. 정답이 아니니 참고만 해주세요.
'Undergraduate Records' 카테고리의 다른 글
OPIC 모의고사 준비 (0) | 2020.04.29 |
---|---|
[운영체제] 세마포어와 뮤텍스의 차이점 (0) | 2020.04.29 |
WEB design - 웹 페이지 디자인 및 스크롤바 색상 바꾸기 (0) | 2020.04.26 |
OPIC TIP - 전략, 카테고리 파악하기 (0) | 2020.04.24 |
이마트 모동숲 에디션 결과 발표 및 스위치(일반)응모 안내 (0) | 2020.04.24 |