오래 못 할 짓 하지 않기

[ 운영체제 ] 15. 동기화와 관련된 문제 해결 본문

3학년 1학기/운영체제 (OS)

[ 운영체제 ] 15. 동기화와 관련된 문제 해결

쫑알bot 2024. 4. 30. 12:17
728x90

https://witch.work/posts/os-5

https://velog.io/@chy0428/OS-HW-support-for-Synchronization

 

위 두 블로그에 정리 잘 되어 있음.

 

 

 

우선 동기화와 관련하여 생기는 문제를 해결하는 방법은 여러 가지가 있다.

하지만 어떠한 방법이든 다음 3가지 조건을 충족해야한다.

 

1. 상호 배제 ( Mutual exclusion ) 
  : Critical section에는 1개의 프로세스만 접근할 수 있다.

 

2. 진행 ( Progress )

   : 자신의 Critical section에 실행되고 있는 프로세스 X

     and Critical section에 들어오려고 하는 프로세스가 있을 때

     → 무기한 연기되지 않고 Critical section에 들어올 수 있어야 한다.

 

3. 한정된 대기 ( Bounded waiting ) 

    : 프로세스가 Critical section에 들어가려고 할 때 각자 들어갈 수 있는 횟수에 제한이 필요하다.

 

 

 


Peterson's Solution

특징

1. 현대 컴퓨터 구조에서는 작동한다는 보장을 할 수 없음

2. 그러나 이 문제 해결하는 알고리즘 설명에는 좋다.

3. 두 개의 프로세스가 int turn / boolean flag[2] 를 공유한다.

 

 

● Peterson's Soulution 1단계 접근

 

turn = 0 으로 초기화하였고

j= 0 , i = 1로 가정해보자

https://witch.work/posts/os-5

 

j 프로세스의 모습이다. ( i 프로세스도 똑같이 생기고, i와 j위치만 바뀌어 있음 )

 

1번 프로세스에서 Critical Section에서 작업을 하고 있다면

do 아래 While에서 기다리고, 다 마치면 turn = 0로 바뀐다.

 

하지만 이는 Progress를 위반한다.

turn = 0 일 때, P1이 준비상태가 되어 Critical section에 들어가려고 하면 turn != 1이라서 

계속 While을 돈다.  

( turn =1 일 때 되어야 하는 애 먼저 시작하면 계속 기다려야 한다는 뜻 같음 )

 

 

● Peterson's Soulution 2단계 접근

https://witch.work/posts/os-5

 

프로세스 개수만큼 flag 를 만든다.

초기값은 모두 false이고

flag[i]가 true면 i번 프로세스가 준비되었다는 의미이다.

 

Progress 위반 

하지만, P0에서 flag[0]이 true가 되고 critical section에 들어가려고 하는데

 그 순간 P1에서 flag[1]를 true가 되게 한다면, 임계구역에는 아무 프로세스도 접근을 하지 못했기에

 둘 다 대기하게 된다.

 

https://witch.work/posts/os-5

 

 

 

● Peterson's Soulution 3단계 접근

 

이번에는 flag랑 turn 둘 다 사용한다.

 

flag 같은 경우에는 둘 다 True일 수 있지만

turn 은 하나만 가능하다.

 

따라서 flag 모두 true로 되어있더라도 turn 값에 따라 조정이 되므로

Critical section에 하나의 프로세스만 진입하는 걸 보장해준다.

 

이 방식은 [ 상호배제 , 진행, 한정된 대기 ] 세 조건 모두 만족한다.

 


● 한계

- 현대 컴퓨터 구조에서는 동작할지는 보장할 수 없다.

- Performance를 올리기 위해서, 프로세서나 컴파일러는 종속성이 없는 작업의 순서를 변경할 수 있다.

    ▶ 이는 MultiThread에서 inconsistent 혹은 unexpected results를 야기한다.

 

→ 이를 해결하기 위해서 하드웨어의 지원을 받는다.

 

 


Synchronization Hardware

● [ 배경 ]

 

Single - core 프로세서면 비선점으로 작동시킬 수 있기 때문에 interrupt 없이 돌아갈 수 있다.

             하지만, 그렇게 돌리기엔 비효율적이라 Multicore로 작동시킨다.

 

● [ 방법 ]

 - Memory Barriers

 - Hardware instructions

 - Atomic variables

 

 

 

Memory Barriers

 

해당 명령어는 LW,SW 같은 연산이 실행되기 전에,

현재 프로세스에서 진행되는 저장 작업이 메모리에서 완료되도록 한다.

 

뭔가 급하게 와다다닥 하려고 할 때

" 얘들아 잠깐 정리하고 천천히 가자." 하는 역할

 

따라서 현재 프로세스에서 실행되어야 하는 LW ,SW 작업을 하고 그 다음 명령어들을 실행한다.

이는 다른 프로세스들도 급하게 섞이는 값들이 아닌 다 정리된 값(동기화 된 값)을 memory에서 참조할 수 있다. 

 

Hardware랑 가까운 명령어이므로 Low level operation

 

 

예제

 

컴파일러와 프로세서는 효율성을 위해 연산 순서를 바꿀 수도 있다.

하지만 memory_barrier는 연산 순서가 섞이지 못하게 해준다.

 

Thread 1에서 조건문에 걸려서 계속 memory_barrier에 있는다.

▶ Thread 2에서 x주소에 100을 넣는다. (무조건 얘가 flag=true보다 먼저 실행됨)

▶ 그 다음 flag = true 실행

▶ 출력은 100.

 

 

 

피터슨 솔루션에 적용하면 다음과 같다.

다른 프로세스들에게 다 멈추고 나 지금 저장한다.

▶ 다들 다시 시작해

 

 

 

https://brightmango.tistory.com/entry/%EB%8F%99%EA%B8%B0%ED%99%94%EB%A5%BC-%EC%9C%84%ED%95%9C-%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4-%EC%A7%80%EC%9B%90

 

 


Hardware instructions

: Hardware 에 관련된 명령어를 한 덩어리로 만들면

 그 사이에는 Interrupt가 생기지 않으므로 값을 바꿔줄 때 Unexpected 값이 생기지 않는다.

 

이렇게 만들어진 명령어는 Atomic하게 실행된다.

 

● Test and Set


https://witch.work/posts/os-5

 

- Lock 변수는 False로 초기화 시킨다.


- 해당 프로세스에서 임계 구역이 끝나면 Lock 변수를 false로 바꾸고 나와서

   다른 프로세스가 접근할 수 있도록 한다.

 

 

● 한계

- Lock 변수가 True라면 계속 사용하므로, Bounded Waiting 조건은 충족시키지 못한다.

  Mutual exclusion은 해결함.

 

 

 

 

 

 

 

● Swap

 

 

현재 주어진 값이 해당 프로세스가 원하는 값인지 판단하는 Atomic한 함수를 만든다.

 

 

 

lock의 값의 기대값 0이면 1을 Return한다.

(그냥 예상값,현재 값  두 개 맞추면 뒤에 마지막 인자를 return한다)

 

 

● 한계

- Lock 변수가 True라면 계속 사용하므로, Bounded Waiting 조건은 충족시키지 못한다.

  Mutual exclusion은 해결함.

 

 

하지만 코드에서 3줄만 추가하면 Bounded Waiting 도 가능하다.

     ▶  다음은 i번 프로세스에서 실행되는 코드이다.

 

 

이 i번째 프로세스가 Critical section에 들어가는 건 두 가지 경우가 있다.

Waiting[i] == False 혹은 key == 0 일 때임.

 

Waiting[i] 가 False가 되는 경우 : 다른 프로세스가 Critical section을 떠날 때

 Key 가 0이 되는 경우 : compare_and_swap에서 lock을 통해서만 가능 ( lock이 1로 바뀌면 탈출 가능 )

 

 

Bounded waiting을 해결하기 위한 부분은 주황색으로 칠해져있다.

근데 이거는 큐 형식으로 해서 계속 볼 수 있게 하는 것 같음

 

 

 

근데 이거 j = ( j+1)%n이어야 하는 거 아닌가 싶음

 

 

 

 


Atomic variable

 

동기화를 위해 사용되는 Compare_and_swap 를 구현하는데 필요한 tool 중에 하나이다.

 

Interrupt 없이 순서를 보장해주는 변수

 

 

 

 

 

(출처)
운영체제 공룡책 6단원 정리 (witch.work)
https://velog.io/@chy0428/OS-HW-support-for-Synchronization
한동대학교 고윤민교수님 - 운영체제