Language/C

C - 세마포어 라이브러리를 이용한 mutual exclusion

ShinyOcean 2021. 6. 22. 20:06

 

 

안녕하세요 :)

 

저번 포스팅에서 우리는 글로벌 변수를 이용한 상호배제를 지켜주는 코딩을 다루어 보았습니다.

 

저의 경우 모자란 코딩 실력 탓에 무식하게 스레드를 선언하고 무식하게 글로벌 변수를 선언하여 코드의 시퀀스와 상관없이 상호배제만 지켜질수 있도록 코딩을 진행해보았는데요.

 

사실 로직을 조금더 이해하고 조금만더 머리를 사용해보면 코드의 진행 시퀀스도 지키면서 상호배제도 이룩할수 있는 방법이 있을것 입니다.

 

하지만 그럴 필요가 있을까요? 저는 그보다는 이미 검증된 라이브러리를 사용하는 것을 거 추천드립니다. 

왜냐하면 상호배제를 지켜줄수 있는 논리적인 방법을 열심히 생각해서 사용하는 것도 물론 큰 의미가 있겠지만, 우리보다 머리가 좋은 사람들이 이미 세마포어라는 검증된 라이브러리를 만들어 두었습니다. 이를 잘 활용하는 것이 시간적으로나 코드의 안정성 부분이나 더 나은 방법일것 같습니다.

 

세마포어는 운영체제 카테고리에서 자세히 다루었으니 이번 포스팅에서는 어떻게 이를 코드내에서 활용하고 어떠한 효과가 있는지 알아보겠습니다.

 

이번에 실습해볼 예제는 글로벌 변수의 사용을 상호배제를 지켜주지 않고 사용했을때와 지켜주고 사용했을때의 차이를 살펴볼것입니다.

 

 

 

 

 

예제 속 개발자의 의도는 스레드와 메인함수내에서 글로벌 변수값을 1올려주는 루프를 각각 10번 씩 돌려 글로벌 +20 이 되도록 하는것이었습니다.

 

스레드 1 : Loc라는 지역변수를 글로벌변수(Glob) 값으로 초기화하고 1초 또는 2초의 딜레이를 갖은후 loc+1을 글로벌 변수에 초기화 하는 작업을 for루프를 통해 10번 수행합니다.

 

 

메인 함수내에서는 위의 스레드가 실행되는 동시에 똑같은 방법으로 글로벌 변수를 사용합니다.

 

 

 

이러한 방법으로 코드를 진행했을때의 결과를 상상해 보겠습니다.

 

1초 또는 2초라는 랜덤한 시간동안의 딜레이를 같고 메인과 스레드1는 Loc +1의 값으로 글로벌 변수를 초기화 하게 됩니다. 그런데 만약 스레드가 딜레이를 1초 갖고 메인이 딜레이를 2초를 갖은 상황에서 글로벌 변수값이 100이라면 어떻게 될까요?

 

2초후에 글로벌은 103이 되어있고 메인의 로컬은 101, 스레드의 로컬은 102가 되어 있으며 메인의 루프는 9번 남고 스레드의 루프는 8번  남을것입니다.

 

중구난방이죠? 개발자의 의도대로 라면 2사이클이 지났을때 글로벌 변수 값이 104가 되는것을 원했을것입니다. 하지만 글로벌 변수를 공유하고 사용함에 있어 각각의 딜레이 시간이 다르기 때문에 예상과 다른 결과값이 나왔습니다.

 

쭉 돌려 보면 서로의 랜덤 딜레이가 (1,1 또는 2,2)로 계속 같지 않다면 값은 예상보다 작게 나올것입니다.

 

결과는 다음과 같습니다.

 

 

위의 경우 메인 함수의 딜레이가 스레드의 딜레이보다 짧은경우가 많이 나왔습니다.

메인에서 글로벌변수의 값이 +2 되었지만, 스레드에서 지역변수 +1된 값으로 초기화를 진행한 루프가 많이 발생한것 같습니다.

 

 

 

그렇다면 원래 의도 대로 스레드에서 +10 메인에서 +10을 하기 위해서는 어떻게 해야할까요?

값을 초기화 해주는 서로의 크리티컬 섹션을 상호배제해주어야 할 것입니다.

 

이번에는 세마포어 라이브러리를 통해 진행해보겠습니다.

 

먼저 크리티컬 섹션을 찾아보면 다음과 같습니다.

 

<스레드의 크리티컬 섹션>

 

 

<메인의 크리티컬 섹션>

 

 

각각의 크리티컬 섹션의 앞뒤로 세마포어 라이브러리의 함수들을 사용해보겠습니다.

하지만 그이전에 세마포어 변수 선언과 초기화가 이루어져야 합니다, 변수는 글로벌 변수로 선언하고 초기화는 메인에서 이루어 져야합니다. 아래와 같습니다.

 

 

 

이후 크리티컬 섹션앞뒤로 wait 과 post 함수를 사용한다면 아래와 같습니다.

 

 

<스레드 function>
<메인>

 

 

이후에 결과를 확인해 본다면 딜레이는 이전 보다 더 많이 걸리게 되겠지만 기대한 값을 도출할수 있습니다.

 

 

 

 

 

 

이번 포스팅까지 Linux 환경에서 C 언어를 이용해 상호배제와 스레드를 다루어 보았습니다. 부족한 코드지만 혹시나 참고하실 분이 있다면 아래에 깃허브 링크를 첨부해 두겠습니다.

 

 

 

https://github.com/Kimhaechan1022/practice/tree/master

 

Kimhaechan1022/practice

Contribute to Kimhaechan1022/practice development by creating an account on GitHub.

github.com