세마포어(Semaphore)?
세마포어(semaphore)는 에츠허르 다익스트라(Edsger Wybe Dijkstra)가 제안한 교착 상태(DeadLock)에 대한 해법으로, 두 개의 원자적(Atomic) 함수로 제어되는 정수 변수입니다. 세마포어는 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제어하기 위해 사용되며, 제한된 개수의 프로세스(Process)나 스레드(Thread)만이 동시에 1개의 공유 자원에 접근할 수 있도록 합니다.
즉, 세마포어는 여러 사람이 동시에 사용하려고 할 때, 특정 자원을 안전하게 사용할 수 있도록 도와주는 도구입니다.
이렇게만 말하면 세마포어가 어떤 도구인 지 감이 안오시죠? 이해하기 쉽게 예를 들어 말씀드려보겠습니다.
영화관 좌석을 예로 들어 설명해보겠습니다. 영화관에 가보신 분은 아시겠지만 영화관 좌석은 한정되어 있습니다.
위 사진에 있는 영화관 좌석은 많은 좌석을 가지고 있지만 10개의 좌석만 영화관에 존재한다고 가정해보겠습니다.
여기서 세마포어는 영화관 좌석의 개수를 나타냅니다. 처음에는 10개의 좌석이 모두 비어있는 상태이기 때문에 세마포어 값도 10이 됩니다.
그 후 시간이 지나자 새로운 관객 1명이 들어오게 됩니다. 새로운 관객 1명이 들어와 영화관에 들어와 좌석을 차지하게 될 때 세마포어 값을 1 감소 시킵니다.
그러니까 세마포어 값이 10에서 9로 줄어들게 된 것이죠. 여기서 더 많은 관객이 들어오게 되면 세마포어 값은 계속 감소하겠죠?
그 상태에서 영화가 시작되었습니다. 시간이 지나서 영화가 끝이났고, 1명의 관객이 영화를 다 보고 나가게 되면서 좌석을 반환하였습니다. 이 때 세마포어 값이 1 증가하게 됩니다. 그러니까 세마포어 값이 9에서 10으로 증가하게 된 것이죠.
이 설명으로 세마포어의 기본적인 동작 설명이 끝났습니다.
세마포어를 설명할 때, 보통 S라는 변수를 사용하여 세마포어의 값을 나타냅니다. 이 값은 현재 사용할 수 있는 자원의 수를 나타내며, 세마포어 연산(P 연산과 V 연산)에 의해 변경됩니다.
그럼 여기서 변수 S, P 연산, V연산에 대해 제대로 살펴보겠습니다.
변수 S
변수S는 자원의 제한된 수와 초기값을 나타냅니다. 각각 살펴보도록 하겠습니다.
자원의 제한된 수
아까 위에서 영화관의 좌석은 한정되어 있었죠? 영화관에 10개의 좌석이 있을 때 변수 S는 현재 사용 할 수 있는 좌석의 수를 나타냅니다.
초기값
세마포어는 초기값을 가진다고 말씀드렸는데 이 말은 동시에 접근 가능한 자원의 최대 수를 나타냅니다.
영화관의 예에서 처음에는 10개의 좌석이 모두 비어 있기 때문에 세마포어 값S도 10이 됩니다.
초기값이 1인 세마포어도 있는데 이 때 초기값이 1인 세마포어는 이진 세마포어(Binary Semaphore) 또는 뮤텍스(Mutex)라고도 합니다. 초기값이 1이기 때문에 하나의 자원만 사용할 수 있죠.
P 연산
P 연산은 세마포어의 값을 감소시키는 연산입니다. 새로운 관객이 영화관에 들어와 좌석을 차지하면 세마포어 값을 1 감소시킵니다. 즉, 세마포어 값이 10에서 9로 줄어듭니다.
관객이 더 많이 들어오면 세마포어 값은 계속 감소하게 되는데 모든 좌석이 이미 차있다면, 자원이 사용 중인 상태이므로 관객은 좌석이 비워질 때까지 기다립니다.
V 연산
V 연산은 세마포어의 값을 증가시키는 연산입니다. 관객이 영화를 다 보고 나가면 좌석을 반환합니다.
이때 세마포어 값이 1 증가합니다. 예를 들어, 세마포어 값이 9에서 10으로 돌아갑니다. 이때, 대기 중인 다른 관객(프로세스나 스레드)이 있다면, 세마포어 값이 증가함에 따라 자원을 사용할 수 있게 됩니다.
세마포어는 실제 어떻게 쓰이는가?
네트워킹에서의 세마포어
서버는 동시에 처리할 수 있는 클라이언트 연결의 수를 제한해야 할 때가 있는데 이를 위해 세마포어를 사용하여 최대 연결 수를 제어합니다.
서버가 동시에 10개의 클라이언트 연결을 허용한다고 가정할 때, 세마포어 초기값을 10으로 설정합니다.
그 후 새로운 클라이언트가 연결을 시도할 때, 세마포어 값을 1 감소시켜 사용 가능한 연결 수를 줄입니다.
만약 세마포어 값이 0일 때, 클라이언트는 연결이 허용될 때까지 기다리게 됩니다.
시간이 지난 뒤 한 명의 클라이언트가 연결을 종료하면, 세마포어 값을 1 증가시켜 사용 가능한 연결 수를 늘립니다.
이 때 대기 중인 클라이언트가 연결이 허용되어 접속할 수 있게 됩니다.
데이터베이스 관리에서의 세마포어
데이터 무결성 : 데이터가 전송, 저장되고 처리되는 모든 과정에서 변경되거나 손상되지 않고 완전성, 정확성, 일관성을 유지함을 보장하는 특성.
데이터베이스에서는 세마포어를 사용하여 여러 트랜잭션이 동시에 데이터에 접근할 때 발생할 수 있는 충돌을 방지해주는데 대표적인 예로 여러 트랜잭션이 동일한 데이터 레코드에 접근하려고 할 때, 데이터 무결성을 유지하기 위해 세마포어를 사용합니다.
특정 데이터 레코드에 대해 동시에 접근할 수 있는 트랜잭션의 수를 제한하기 위해 세마포어 초기값을 설정합니다.
일반적으로 이 값은 1입니다.
트랜잭션이 데이터 레코드에 접근하려고 할 때, 세마포어 값을 1 감소시켜 접근을 제어합니다.
만약 세마포어 값이 0이라면, 다른 트랜잭션이 작업을 완료할 때까지 기다립니다.
트랜잭션이 데이터 레코드에 대한 작업을 완료하면, 세마포어 값을 1 증가시켜 다른 트랜잭션이 접근할 수 있도록 합니다.
멀티스레딩 프로그래밍에서의 세마포어
멀티스레딩 환경에서는 세마포어를 사용하여 여러 스레드가 동시에 공유 자원에 접근할 때 발생할 수 있는 충돌을 방지해주는데 대표적인 예로 공유 자원 접근 제어가 있는데 여러 스레드가 동일한 메모리 공간이나 파일에 접근하려고 할 때, 세마포어를 사용하여 접근을 제어합니다.
공유 자원에 대해 동시에 접근할 수 있는 스레드의 수를 제한하기 위해 세마포어 초기값을 설정합니다. 예를 들어, 최대 3개의 스레드가 동시에 접근할 수 있도록 초기값을 3으로 설정할 수 있습니다.
스레드가 공유 자원에 접근하려고 할 때, 세마포어 값을 1 감소시켜 접근을 제어합니다. 만약 세마포어 값이 0이라면, 자원이 사용 가능해질 때까지 기다립니다.
스레드가 공유 자원에 대한 작업을 완료하면, 세마포어 값을 1 증가시켜 다른 스레드가 접근할 수 있도록 합니다.
오늘은 세마포어에 대해 알아보았습니다. 세마포어는 여러 프로세스나 스레드가 공유 자원에 동시에 접근할 때 발생할 수 있는 충돌과 교착 상태를 방지하는 중요한 도구입니다. 이를 통해 시스템의 안정성과 효율성을 높일 수 있습니다. 세마포어는 운영체제뿐만 아니라 네트워킹, 데이터베이스 관리, 멀티스레딩 프로그래밍 등 다양한 분야에서 널리 사용됩니다.
세마포어에 대한 이해를 통해 동시성 제어와 자원 관리의 기본 원리를 파악할 수 있으며, 이를 바탕으로 더 안정적이고 효율적인 소프트웨어를 설계할 수 있습니다.
'프로그래밍(Basic) > 이론' 카테고리의 다른 글
[바미] 피터슨 알고리즘 (0) | 2024.06.12 |
---|---|
[바미] 철학자의 식사시간 문제 (0) | 2024.06.11 |
[바미] On-premises와 Off-premises (0) | 2024.03.22 |
[바미] SSR과 CSR (0) | 2023.09.25 |
[바미] WebSocket과 Socket.io차이는 무엇일까? (0) | 2023.05.11 |