티스토리 뷰

공유 자원에 접근하고자 하는 두개의 쓰레드 a,b가 있다고 해보자. 이때, 공유 자원은 한번에 하나의 쓰레드만 접근해야 race condition이 발생하지 않기 때문에 하나의 쓰레드가 공유자원을 사용중이라면 다른 쓰레드는 그 쓰레드가 공유 자원을 모두 사용할때까지 기다려야 한다.


이때, 기다리는 쓰레드가 공유 자원을 사용할수 있는지 없는지 계속해서 무한 루프를 돌면서 조건문을 체크하는 방식이 busy waiting이다.

이 바쁜대기라고 불리는 busy waiting은 cpu의 자원을 쓸데없이 낭비하기 때문에 좋지 않은 쓰레드 동기화 방식이다.


그렇기 때문에 쓰레드의 동기화를 위해서 busy waiting 방법을 쓸게 아니라 , 뮤텍스 세마포어(mutual exclusion) 또는 모니터를 사용해야 한다. 이방법은 씨피유가 계속해서 락을 얻을 수 있는지 쓸데없이 무한 루프를 돌면서 확인하는게 아니라, 어떤 쓰레드가 공유 자원을 획득한 경우 다른쓰레드는 그 쓰레드가 공유 자원을 모두 사용할때까지 잠잠히 기다린다. 그리고, 그 쓰레드가 공유 자원을 모두 사용하면 그때 기다리고 있던 다른 쓰레드를 깨우는 방식이다. 이렇게 하게 되면 쓸데없이 기다리는 쓰레드가 공유 자원에 접근할 수 있는지 지속해서 확인할 필요 없이 기다리다가 알아서 깨워주기 때문에 훨씬 자원의 낭비가 덜하다.


모니터를 사용하게 되면 뮤텍스락(할당,해제)의 관리를 알아서 해주기 때문에 좀 더 간단하지만, 시스템 별로 뮤텍스락만 지원하는 경우가 있고 모니터를 지원하는 경우가 있기 때문에 모니터가 사용 가능 하다면 웬만하면 모니터를 사용하는것이 좋을것이다. 뮤텍스 세마포어를 사용하는 경우 모니터를 사용하는것과 똑같은 효과를 낼 수 있긴 하지만, 사용자가 직접 락을 얻고 해제하는 코드를 작성해야 하며, 실수로 크리티컬 섹션을 뮤텍스 락으로 감싸는것을 깜빡할수 있는 실수의 여지도 생기기 때문에 웬만하면 모니터를 사용하는것이 좋다. 물론, 잘만 사용한다면 뮤텍스 세마포어 방식도 모니터와 같은 효과를 낼 수 있다.모니터는 뮤텍스 락으로 감싸져있다. 뮤텍스락을 얻은 뒤에 공유 자원에 접근하고, 다 사용한 다음엔 뮤텍스 락을 해제 한다. 뮤텍스 세마포어도 같은 방식이다.


사용할 수 있는 공유 자원의 개수가 1개가 아니라 여러개일 경우 카운팅 세마포어를 사용한다. 공유 자원이 6개가 있을때 12개의 쓰레드가 동시에 돌고 있을때 한번에 6개의 쓰레드가 공유 자원에 접근해도 문제가 발생하지 않을 것이다. 하지만 그 이상 접근하면 race condition이 발생한다. 그렇기 때문에 공유 자원의 개수를 카운팅 하면서 락을 걸어야 한다. 즉, 현재 사용 할 수 있는 자원이 몇개인지를 카운트하는데, 0개인 상태에서 다른 쓰레드가 또 그 공유 자원에 접근하려고 하는 경우 그 쓰레드 부터는 막아야 한다. 그리고 나서, 현재 공유 자원을 쓰고 있던 쓰레드중 하나가 사용을 다 한 다음에 뮤텍스 락을 반납한 경우 그 기다리고 있던 쓰레드 중 하나를 깨워서 크리티컬 섹션에 입장 시킨다. 이런 방식으로 쓰레드를 동기화 하는 방법이 카운팅 세마포어이다. 결국엔, 그냥 뮤텍스 세마포어 인데 공유 자원이 여러개인것만 다른것이다.


여기서 질문

Q. Busy Waiting란 용어를 설명해보고 어떻게 하면 바쁜 대기를 피할 수 있는가?

A. 바쁜 대기란, A와 B라는 두개의 쓰레드가 공유 자원을 사용하려고 할때 a쓰레드가 공유 자원을 먼저 사용하게 되면 b쓰레드는 a쓰레드가 사용을 마칠때 까지 기다려야 한다. 이때 b쓰레드는 a쓰레드가 공유 자원 사용을 끝냈는지 계속 무한 루프를 돌면서 확인하게 되는데 이것이 바쁜 대기이다. 이것을 해결하기 위해서는 세마포어, 모니터 두가지 방식이 있다. 세마포어의 경우 공유 자원을 사용하기 전에 뮤텍스 락을 얻고, 다 사용하고 나서는 뮤텍스 락을 해제한다. 뮤텍스 락을 갖고 있는 동안 다른 쓰레드는 공유자원에 접근하지 못한다. 그리고 락을 해제하는 순간 다른 쓰레드가 깨어나기 때문에, 바쁜대기를 할때 처럼 cpu자원을 낭비할 필요도 없다. 모니터는 세마포어에서 뮤텍스 락을 얻고 해제하는 부분이 자동으로 된다는 점만 빼고는 거의 세마포어와 비슷하다.



cf) 동기화란?

보통 영화를 볼때 화면과 소리가 안맞을때가 있다. 이때 우리는 영화 파일의 싱크가 맞지 않는다고 표현하는데, 이것이 바로 동기화(syncronize)되어 있지 않다는 의미이다. 즉, 어떤 두개(화면,소리)가 일치하지 않는다 = 동기화되지 않았다 를 의미한다.

쓰레드의 동기화라는 뜻은 두개이상의 서로 다른 쓰레드가 서로 알고 있는 데이터가 일치하게끔 만들어준다. 라는 의미이다.

만약에 공유 자원에 대해 여러개의 쓰레드가 동시에 접근할 경우 race condition(경쟁상태)가 발생하기 때문에 공유 자원(전역변수등)의 값이 꼬이게 될 가능성이 매우 높다. 이때 여러개의 쓰레드가 서로 자신이 알고 있는 값이 다르다. 즉, 쓰레드 끼리 동기화 되어 있지 않다.

그렇기 때문에 쓰레드의 동기화라는 의미는, 쓰레드가 알고 있는 값들을 서로 일치시켜주겠다는 뜻이고 그말은 결국 공유 자원에 대해 여러개의 쓰레드가 동시에 접근하는것을 막겠다는 의미이다. 그말은 또 다르게 보면 공유 자원에 접근하는 코드 부분(critical section)에는 한번에 하나의 쓰레드만 입장시키겠다는 뜻이다. 

기억 하기 쉽게 좀 더 쉽게 말해보면 쓰레드의 동기화 = critical section에 한번에 하나의 쓰레드만 입장시키는것 을 의미한다.




'컴퓨터 공학과 졸업 > 운영체제' 카테고리의 다른 글

스케쥴링 알고리즘  (0) 2018.10.17
식사하는 철학자 문제 요약  (0) 2018.08.10
메모리  (0) 2017.12.06
쓰레드 사용 예 및 구현 방법  (0) 2017.10.17
쓰레드  (0) 2017.10.14
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함