1 minute read

윈도우의 프로세스와 스레드 (7)

세마포어

세마포어는 다익스트라에 의해 제시된 개념으로 철학자들이 굶어죽는 문제를 처음으로

제기한 이가 다익스트라입니다.

세마포어는 병렬적인 리소스와 그 리소스를 차지하는 스레드 사이의 다대다 관계로 해석하면됩니다.

세마포어는 철도의 신호기에서 온것으로 하나의 철길을 두개 이상의 기차가 이용하기 위해 신호를 따른다는 의미입니다.

뮤텍스가 한번에 단 하나의 보호되는 자원을 설정할수있음에 반해, 세마포어는 해당 자원을 몇개의 스레드가 동시에 사용할수있을지 정의합니다.

일반적으로 뮤택스를 하나의 스레드만이 접근할수있는 까닭에 바이너리 세마포어라고 일컫기도 하지만,

윈도우 시스템에서는 최대 하나의 스레드만이 접근할수있는 세마포어와 뮤텍스는 완전히 다른 개체로 인정되므로

처음부터 뮤텍스로 설정한것과 세마포어로 설정한것은 차이점을 갖는다는 사실을 잊어서는 안됩니다.

뮤텍스나 세라포어는 스레드를 순서대로 동작을 시키는데 주안점을 맞추므로 실제 CPU 활용상황에서 그렇게 최적화되지 못하는 경우가 많습니다.

하나의 리소스를 잠금 설정했을경우 해당 리소스에 복수접근이 가능하더라도 최대 접근 수는 항상 1로 설정되기 때문에

결국 멀티스레드 프로그램에서 나타나는 복수 스레드가 특정 자원을 뮤텍스로 감쌌을경우 여러 스레드 사이에서 대기 상태가

계속 나타나게 됩니다.

이는 컨텍스트 전환이후 아이들링 상태의 CPU 동작을 빈번히 가져오게 되며 결국 프로그램은 멀티스레드의 이점을 최대한 활용할수없습니다.

세마포어는 하나의 자원 혹은 루틴에 최대접근 숫자를 정의해놓고 접근 숫자가 모두 차면 여분의 접근 숫자를 0으로 설정합니다.

이후 여분 접근 숫자가 0이 아니면 그만큼 스레드의 요청을 받아드릴수없습니다.

따라서 잘못설계하게 되면 세마포어는 멀티스레드가 갖는 문제를 그대로 나타내게 됩니다.

단지 동시에 동작할수있는 스레드의 수만 한정해놓는 셈입니다.

따라서 상호간섭이 나타나는 리소스에는 세마포어를 사용할수없습니다.

가령 열차 화장실 문제로 다시 복귀해서 화장실이 모자라서 하나를 증설하는경우, 뮤텍스나 크리티컬 섹션으로는 동작하지않고 세마포어로 동작하게됩니다.

그러나 화장실로 가는 스레드가 동시에 두개까지 허용된다는것은 실제 화장실이 두개인것을 의미합니다.

따라서 화장실이 하나임이도 불구하고 스레드를 두개만들면 어쩔수없이 경쟁상태를 가지게 됩니다.

세마포어가 가장 효율적으로 사용되는곳은 데이터베이스의 커넥션 작업입니다.

보통 데이터베이스 접근과 같은 작업들은 멀티스레딩으로 처리하는 경우가 많은데, 실제로 데이터 베이스 연결은

라이선스, 혹은 성능에 의해 최대 연결가능 숫자가 지정되어있습니다.

따라서 정의한 숫자 이내의 연결을 위해서 리소스를 사용하는 스레드를 컨트롤해야합니다.

단 하나의 리소스만을 사용할 경우에는 뮤텍스를 쓸수있겠지만, 리소스가 두개이상이

될 경우에는 효율적인 시스템 운영을 위해서 세마포어를 사용할수밖에없습니다.

세마포어는 뮤텍스와 약간 다른 방법으로 동작합니다.

뮤텍스가 전역변수로 설정된것에 반해 세마포어는 지역 변수로 설정됩니다.

세마포어는 동시에 다중참조가 가능한 커널객체 이므로 세마포어 이름을 알고있다면, 일단 생성되어있는 세마포어를 열어 사용할수있기때문입니다.

따라서 주 스레드 에서 세마포어를 연뒤 파생되는 스레드에서 세마포어를 사용할수있는 체계가 확립되는 셈입니다.

Reference

  • https://karfn84.tistory.com/entry/%ED%8E%8C%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9C%88%EB%8F%84%EC%9A%B0%EC%9D%98-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C

Categories:

Updated: