https://www.codeproject.com/Articles/5345515/Between-Mutex-Semaphore-and-Horrible-Hairdos
끔찍한 머리 모양의 유행하던 시절로 돌아가보면 단일 시스템에서 프로그램의 여러 인스턴스를 반복적으로 실행하는 것이 가능했죠: 여러 개의 창이 끊임없이 하나씩 열렸습니다.
오늘날은 대부분의 경우에 우리는 시스템에서 프로그램은 한 번만 실행되도록 하고 싶을 겁니다.
뮤텍스 혹은 세마포어는 비재귀적 문법을 제공하기때문에 프로그램이 한 번만 실행되며 헤어스프레이가 필요하지 않습니다.
소개
뮤텍스와 세마포어, 세마포어와 뮤텍스 — 두 이름 모두 의사가 처방하는 처방전과 약간 비슷하게 들리지만 뮤텍스 및 세마포어는 컴퓨터 프로그래밍의 두 가지 기본 개념입니다.
그러나 이러한 개념이 무엇인지 설명하기 전에 처음으로 가보시죠 - 그리고 우리의 이 "시작"이라는 의미는 하면 초기 컴퓨터 프로그램를 의미합니다: 끔찍한 헤어스타일, 엄청난 양의 헤어스프레이, 그리고 엷어져가는 오존.
당신도 알겠지만, 80년대와 90년대 초반의 즐거운 시절로 돌아가보면 하나의 머신에서 프로그램을 반복해서 실행할 수 있었다는 사실이 기억날 수도 있을 것입니다: 여러 창이 그위에 또 장이, 그리고 당신은 같은 프로그램의 창을 계속적으로 더 많이 많이 열수 있습니다. 때로는 컴퓨터 리소스 부족으로 인해 컴퓨터가 죽어 버리겠죠
오늘날은 대부분의 경우에 우리는 시스템에서 프로그램은 한 번만 실행되도록 하고 싶을 겁니다.
예를 들어 같은 컴퓨터에서 같은 Excel 문서를 두 번 열고 두 사람이 각각 작업한다고 생각해 보십시오.
분명하게도, 하나의 문서의 이름을 바꾸지 않는다면, 우리는 동일한 파일의 두 인스턴스에서 어떻게 변경 사항을 관리할 수 있을까요? 그래서 MS Office는 당신이 한 번에 하나의 문서 인스턴스만 실행할 수도록 압니다.
또한 사무실 사람들이 사용하는 회계 소프트웨어를 가지고 있다고 가정해 보겠습니다. 동일한 시스템에서는 이 프로그램을 여러 번 실행할 이유가 없습니다.
또한 이는 사용자 친화적인 디자인의 문제이기도 합니다.
사용자가 소프트웨어가 실행 중임을 모르고 새 인스턴스를 시작하려하면 실행시키는 대신 이미 실행 중인 항목에 포커스를 맞춰 줄 것입니다.
여기에는 또 다른 면이 있습니다: 때로는 일부 코드가 동시에 공유 리소스에 액세스하지 않도록 해야 할 것입니다.
코드가 철도망안에서 달린다고 생각해보세요:
당신은 이 두 코드가 동시에 같은 선로에서 달리는 것을 원하지 않습니다 - 우리는 코드가 동기화되고 각 코드가 고유한 일정에 따라 운행되기를 원합니다.
우리 프로그램은 전체 구성 요소와 리소스가 동기화 상태에서 실행되어야 합니다(역시나 비동기적으로 실행되는 일부 프로그램도 있음).
이제 문제에 대해서 이해했으니 솔루션 중 하나인 Mutex(Mutual Exclusion Object)를 소개할 수 있게 되었네요:
C++ 표준 라이브러리에는 공유 리소스를 여러 스레드 또는 인스턴스에서 동시에 액세스하지 못하도록 보호하는 데 사용되는 메커니즘으로 std::mutex를 제공합니다.
기본 유형인 Mutex는 배타적이고 비재귀적인 소유권이라는 의미 체계를 제공합니다.
프로그램 또는 프로그램 내의 스레드와 뮤텍스를 소유한 코드 블록은 다른 인스턴스 또는 스레드가 동일한 프로그램, 스레드 또는 코드 블록을 실행할 수 없도록 보호합니다 — 코드가 잠겨 있으며 주어진 시간에 한 번만 실행되도록 할 것입니다.
다른 리소스가 이미 잠근 상태에서 해당 뮤텍스에 대한 소유권을 얻으려는 시도는 잘못된 값 즉, false를 반환 할 것이므로 호출 당사자는 이미 잠겨 있음을 알 수 있습니다.
예제로 돌아가서 만약 회계 소프트웨어의 뮤텍스가 잠겨 있으면 우리는 이미 실행 중인 해당 소프트웨어의 인스턴스를 찾아서 포커스를 변경시켜 주면 될 것입니다.
뮤텍스가 음성 메일인 경우를 생각해 봅시다 - 누군가 유선 전화로 전화를 걸어 음성 메일에 메시지를 녹음하기 시작하면 다른 사람이 동시에 전화를 걸어 메시지를 남길 수 없습니다 - 음성 메일이 잠기는 것이죠.
한 사람이 메시지 녹음을 마치면 다른 사람이 전화를 걸어 메시지를 남길 수 있을 것입니다.
이 경우의 "뮤텍스"는 당신의 음성 메일에 로컬입니다. 다른 사람에게 메시지를 남길 수 있지만 누군가가 메시지를 녹음하는 동안에는 특정 음성 메일에는 잠겨 있습니다.물론 한 번에 최대 5개 또는 10개의 메시지를 녹음할 수 있는 음성 메일을 설계할 수 있지만 대부분의 음성 메일은 설계상 단일 녹음을 허용 할 것입니다.
이것이 뮤텍스의 상당히 기본적인 아이디어입니다 - 현재까지는 더 많이 알 필요는 없습니다.
세마포어 — 모든 것은 열차 신호로부터 시작되었다.
리소스에 대한 액세스를 제어하는 또 다른 방법은 프로그램을 동기화하는 데 도움이 되는 세마포어를 사용하는 것입니다. 이 방법은 네덜란드 컴퓨터 과학자인 Edsger W. Dijkstra가 1965년에 기차 신호를 위한 방법으로 세마포어를 처음 설계했습니다.
세마포어는 스레드 간에 공유되는 변수이며 하나의 큐와 하나의 카운터의 데이터 구조로 단순화할 수 있습니다. 카운터는 0 또는 0보다 큰 값으로 초기화됩니다.
이 구조체를 사용하여 세마포어는 매우 간단한 두 가지 핵심 작업을 실행합니다.
wait — 세마포어가 wait를 획득할 때 카운터가 0이 아니면 다른 스레드가 계속 사용하고 있는 것입니다. 따라서 초기 값이 10이면 10개의 스레드가 이 리소스를 사용할 수 있으며 각 스레드가 획득할 때 세마포어, 카운터는 0에 도달할 때까지 감소합니다.
Signal 혹은 release — 리소스를 사용하여 스레드가 완료되면 signal 또는 release 작업을 사용하여 세마포어를 해제하게 되므로, 이 경우 카운터가 증가합니다.
이 개념이 너무 혼란스럽다면 Covid-19 시대에 편의점의 경비원으로 세마포어를 생각해 봅시다:
어떤 순간에 폐쇄된 구내에 머무를 수 있는 사람은 소수에 불과 했습니다. 하나의 큐가 있으면 누군가의 접근이 허용 됩니다.
세마포어에서 'wait'는 누군가를 들여보내고, 한 사람 들어갈 수 있는 사람들의 카운터를 줄이는 것을 의미하며, 그 카운터가 이제 0이 되면 아무도 들어갈 수 없게 됩니다.
누군가가 가게를 떠나는 순간(“release”), 카운터는 1 감소하게 되고 다른 사람이 들어갈 수 있습니다.
원래 디자인이었던 열차 신호 장치와 비교해 볼 수도 있을 것입니다.
뮤텍스와 세마포어의 차이점이 무엇인지 스스로에게 물어볼 수 있을 것입니다.
이에 대한 간단한 대답은 뮤텍스는 잠금 메커니즘만 제공하는 반면 세마포어는 신호 메커니즘을 사용한다는 것입니다.
물론 다양한 차이점이 존재 하며 뮤텍스와 세마포어에 대해 더 많은 것을 배울 수 있지만 기사 하나로는 감당 할 수 없습니다.
이상.
'프로그래밍' 카테고리의 다른 글
당신 손안에 사이언스 소프트웨어 (0) | 2022.12.12 |
---|---|
웹 요청 순서 시각화 (0) | 2022.12.11 |
데이터 사이언스을 위한 C/C++ (1) | 2022.12.08 |
테스트 오케스트레이션: What, Why, and How? (0) | 2022.12.06 |
세가지 점근적 분석법 (0) | 2022.12.05 |