프로그래밍(Basic)/이론

[바미] 세마포어

Bami 2024. 6. 10. 09:04
728x90
반응형

세마포어(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 증가시켜 다른 스레드가 접근할 수 있도록 합니다.


오늘은 세마포어에 대해 알아보았습니다. 세마포어는 여러 프로세스나 스레드가 공유 자원에 동시에 접근할 때 발생할 수 있는 충돌과 교착 상태를 방지하는 중요한 도구입니다. 이를 통해 시스템의 안정성과 효율성을 높일 수 있습니다. 세마포어는 운영체제뿐만 아니라 네트워킹, 데이터베이스 관리, 멀티스레딩 프로그래밍 등 다양한 분야에서 널리 사용됩니다.

세마포어에 대한 이해를 통해 동시성 제어와 자원 관리의 기본 원리를 파악할 수 있으며, 이를 바탕으로 더 안정적이고 효율적인 소프트웨어를 설계할 수 있습니다.

728x90
반응형