Kim Seon Deok

[OS] Thread, Process Synchronization, Semaphore 본문

운영체제

[OS] Thread, Process Synchronization, Semaphore

seondeok 2022. 11. 27. 03:29

 

 

 

 

 

 

운영체제에서 중요한 것 → 프로세서 관리

  • CPU 스케줄링 FCFS, SJF, priority scheduling, Round Robin, Multilevel queue, Multilevel feedback queue
  • 프로세스 동기화

 

 

 

쓰레드란?

 

쓰레드는 프로그램 내부의 흐름, 맥이다. 

기존의 os & 요즘의 os

하나의 프로그램에는 기본적으로 하나의 스레드가 존재한다. → 단일 스레드 방식

기존 os는 일정시간이 지나면 다른 프로세서로 넘어가는 형태이다. → context switching 단위 : 프로세서

현재 os는 일정시간이 지나면 프로세서 내부 다른 쓰레드로 넘어간다. → context switching 단위 : 쓰레드

 

스레드는 프로세서의 코드와 데이터가 포함된 메모리를 서로 공유한다. 

하지만 스위칭되면 다른 스레드로 가야하므로 PC값, 레지스터, SP, 스택은 공유하지 않는다.

 

 

Multithreads

 

하나의 프로그램에 2개 이상의 쓰레드가 있는 것을 다중 스레드방식이라 한다.

맥이 빠른 시간간격으로 스위칭 되어 여러 맥이 동시에 실행되는 것처럼 보이는 효과가 있다.

 

 

 

프로세스 동기화 (Process Synchronization)

 

컴퓨터 내부 프로세스 독립적이지 않고 서로 cooperating 관계이다. 따라서 공통된 자원에 서로 접근하려 하다보니 다른 프로세서에 영향을 주거나 영향을 받는다.

공유된 데이터에 동시 접근(concurrent) 하는 것은 데이터 비일관성(data inconsistency)을 초래한다.

따라서 서로 영향을 주고받는 프로세서 간에 순서를 잘 매겨서 데이터의 일관성을 유지해야 한다.

 

 

Bank account problem

 

class BankAccount
{
	int balance;
    
    void deposit(int amount)
    {
    	balance = balance + amount;  // Parent deposit
    }
    
    void withdras(int amount)
    {
    	balance = balance - amount;  // Child withdraw
    }
    
    int getBalance
    {
    	return balance;  // 잔액 확인
    }
}

parent는 통장에 일정 금액을 입금하고, child는 일정금액을 통장에서 출금한다.

입금 금액과 출금 금액이 같다면 최종 잔액이 0원이 되어야 하는데, 그렇지 못한 경우가 발생한다. 

 

∵ parent 업데이트 도중 child 업데이트가 일어나기 때문 공통변수에 대한 동시 업데이트로 인해 시간지연 발생

∴ 한번에 한 스레드만 업데이트 하도록 해야 한다.   임계구역 문제

 

 

 

 

임계구역(Critical section) 문제

 

임계구역이란 여러 개의 스레드가 공통적으로 사용하는 부분이 있는데, 그 부분을 업데이트 하는 구간을 말한다.

여러개의 스레드로 이루어진 시스템에서 각각의 스레드는 'critical section'이라 불리는 코드 영역을 갖고 있다. common 변수를 바꾸거나 table을 업데이트 하거나, file을 쓰거나 하는 것이 critical section이다.

 

 

임계구역 문제의 해결 3가지를 충족해야 한다.

1. Mutual exclusion (상호배타) : 오직 한 스레드만 진입

2. Progress (진행) : 진입 결정은 유한 시간 내

3. Bounded waiting (유한 대기) : 어느 스레드라도 입구에서 기다리고 있다면 유한 시간 내 임계구역에 들어갈 수 있음

 

 

 

 

동기화 도구 

  • 세마포 가장 전통적인 동기화 해결 소프트웨어 도구
  • 모니터
  • MISc

지연시간이 있더라도 안전하게 입금, 출금하고 잔액이 정확하게 맞아떨어지는 건 세마포, 모니터 등의 동기화 도구를 사용하기 때문이다. 따라서 동기화는 동시에 많은 프로세서들이 하나의 자원에 접근할 때 생기는 오류를 막아주는 중요한 역할을 한다.

 

 

세마포

 

세마포는 동기화 문제 해결을 위한 소프트웨어 도구이다.

정수형 변수와 acquire동작(P.Proberen)과 release동작(V.Verhogen)으로 구성된다.

Parent가 임계구역에 있다면 child는 기다려야 한다. parent가 임계구역에서 업데이트 중인데 context switch가 일어나 child가 수행되면 잔액이 0으로 맞지 않게 된다.

 

 

void acquire()
{
	value--;  //  1 감소
    if (value < 0)  
    {
    	add this / process / thread to list; // 프로세서 / 스레드를 큐에 넣음
        block;   // 누가 꺼내기 전까진 가로막혀 있음
    }
}

void release()
{
	value++;   // 1 감소
    if (value <= 0)
    {
    	remove a process P from list;  // 한 프로세서를 큐에서 배냄
        wakeup P;  // P를 깨움
    }
}

cpu가 acquire 호출했는데 조건이 맞지 않으면 프로세서는 device queue로 가지 않고 세마포로 감

ready queue로 가지 못하고 block 됨

 

세마포에 release 호출했는데 조건이 맞으면 세마포의 queue에서 한 프로세서를 빼내서 ready queue로 보냄 = wake up

 

 

 

세마포의 일반적 사용

 

1. Mutual exclution

sem.acquire();
critical section
sem.release();
<Parent>
sem.acquire();
balance = balance + n;
sem.release();


<Child>
sem.acquire();
balance = balance - n;
sem.release();

mutual exclusion 하기 위해서 value = 1로 초기화. number of permit 들어갈 수 있는 것 최대 1개

 

 

Parent 먼저 돌아간다 가정

Parent) 세마포에 들어가서 acquire 호출하면 value = 0 됨.   if 문 만족x

↓context switching

 

Child) 세마포에 들어가서 acquire 호출하면 value = -1 됨. if 문 만족 세마포 큐에 갇혀 블락됨

∴ balance = balance - n; 수행 불가

mutual exclusion에 의해 child가 들어가면 parent는 절대 세마포 큐로 들어갈 수없음

parent) balance = balance + n; 까지 돌고 sem.release();

value = 0 됨 → if문 만족 → 큐에서 블락됐던 child를 빼내서 ready queue로 보냄

child) balance = balance + n; 까지 돌고 sem.release();

parent) 세마포에 들어가서 acquire 호출하면 value = -1 됨. → if문 만족 → 세마포 큐에 갇혀 블락됨

child) balance = balance - n; 까지 돌고 sem.release();

 

 

 

 

2.Ordering

 프로세서의 실행순서를 원하는 대로 제어 가능하다.

 

  • parent 먼저(pppppppccccccccpppppppcccccc...)

sem.value = 0 

parent child
  sem.acquire();
deposit withdraw
sem.release();  

 

  • child 먼저(cccccccppppppppcccccccpppppppp....)

sem.value = 0 

parent child
sem.acquire();  
deposit withdraw
  sem.release();

 

  • parent child 번갈아(pcpcpcpcpcpcpcpcpcpcp...)

dsem.value = 0

wsem.value = 0

parent child
deposit wsem.acquire();
wsem.release(); withdraw
dsem.acquire(); dsem.release();

 

 

 

 

 

 

 

 

'운영체제' 카테고리의 다른 글

[OS] Deadlocks, Monitors  (0) 2022.11.29
[OS] Classical Synchronization Problems  (2) 2022.11.29
[OS] Process Management, CPU scheduling  (0) 2022.11.23
[OS] OS service  (0) 2022.11.23
[OS] Interrupt, Dual mode, HW Protection  (0) 2022.11.23
Comments