ecsimsw

Process Synchronization 본문

Process Synchronization

JinHwan Kim 2019. 9. 26. 14:19

Critical section problem

 

   - 멀티 스레딩을 이용하여 공통된 변수를 다룰 경우 각각의 스레드가 어느 순간에 변수를 엑세스하는가에 따라 결과값이 다를 수 있다는 문제가 발생할 수 있다. 

 

   - 이런 Common variable을 update하는 code section을 Critical section이라고 한다.

 

ex1) 값이 10인 정수형 변수 i를 두 스레드 A,B에서 각각 i++ 을 실행한다고 생각해보자.

 

"정상적인 경우"

  i=10이 메인 메모리에 저장되어 있음

  1. thread A) 메인 메모리의 i=10를 꺼내 연산을 위해 레지스터에 저장

  2. thread A) 레지스터의 i=10에 1을 더해 i=11 값을 얻음

  3. thread A) i=11을 메인 메모리에 저장 후 context switch

  4. thread B) 메인 메모리의 i=11를 꺼내 연산을 위해 레지스터에 저장

  5. thread B) 레지스터의 i=11에 1을 더해 i=12 값을 얻음

  6. thread B) i=12을 메인 메모리에 저장 후 context switch

  i=12이 메인 메모리에 저장되어 있음

"자원이 동시에 접근"

  i=10이 메인 메모리에 저장되어 있음

  1. thread A) 메인 메모리의 i=10를 꺼내 연산을 위해 레지스터에 저장

  2. thread B) 메인 메모리의 i=10를 꺼내 연산을 위해 레지스터에 저장

  3. thread A) 레지스터의 i=10에 1을 더해 i=11 값을 얻음

  4. thread B) 레지스터의 i=10에 1을 더해 i=11 값을 얻음

  5. thread A) i=11을 메인 메모리에 저장

  6. thread B) i=11을 메인 메모리에 저장

  i=11이 메인 메모리에 저장되어 있음

 

i라는 전역 변수 자원이 두 스레드에서 사용되면서 동시에 i 값을 읽어와 원치 않았던 결괏값을 얻었다.

 

  ex2) 실제 코드로 확인하였다. i=10에 threadA에선 1을 더하고 threadB에선 10을 곱한 후 최종 결과 i 를 출력한다.

 

 class Program {

      static int i = 10;

      static void Main(string[] args) {

              Thread threadA = new Thread(new ThreadStart(Add));

              Thread threadB = new Thread(new ThreadStart(Mul));

              threadA.Start();

              threadB.Start();

              Thread.Sleep(1000);

              Console.WriteLine(i);

       }

       static void Add() {

              for (int j = 0; j < 3; j++) {

                   i ++;

                  Console.WriteLine("add "+ i);

                  Thread.Sleep(100);

              }

       }

       static void Mul() {

              for (int j = 0; j < 3; j++) {

                   i*=10;

                   Console.WriteLine("mul "+i);

                   Thread.Sleep(100);

               }

        }

   }

 

  i는 스레드에 임의의 딜레이(처리시간)에 따라 매 실행마다 다른 i를 출력한다.

 

Synchronization

 

   동기화란 여러 프로세스 또는 스레드가 공통된 자원을 안전하게 처리하기 위한 처리를 의미한다. 이는 아래 세가지 원칙을 따라야한다.

 

   1. Mutal exclusion : 상호배타. 임계 구역에는 한 스레드만이 진입되어야 한다.

  

   2. Progress :  진입 결정은 유한 시간 내, 누가 먼저 들어갈지 미리 결정되어야 한다.

 

   3. Bounded waiting : 진입이 결정되고 대기 후에는 유한 시간 내에 진입되어야 한다. 즉 대기는 유한해야 한다.

 

Lock

   

   프로세스가 임계구역을 사용 중일 때, 다른 프로세는 사용하지 못하게 막는 것이다.

 

   확인 변수(ex, boolean isHeld)를 두고 임계구역에 들어가는 프로세스는 이 확인 변수를 확인하여 현재 진입이 가능한지를 파악하고, 진입이 가능하면 변수를 바꾸고 진입한다. 임계 구역 사용이 마치면 확인 변수를 초기화하고 빠져나온다.

 

   프로세스가 이미 임계구역을 사용 중이라면 확인 변수가 사용 종료를 표시할 때까지 변수 확인을 반복하는 루프에 빠진다. 이 쓸데 없는 cpu 낭비 문제를 busy wait 라고 한다.  

'Computer Science > Operating system' 카테고리의 다른 글

Traditional synchronization example / Producer and Consumer problem  (0) 2019.10.02
Semaphore  (0) 2019.10.02
Process / Thread  (0) 2019.09.26
Cpu scheduling  (0) 2019.09.24
Process Management / job queue  (0) 2019.09.23
Comments