본문 바로가기

잡동사니

[study: OS] — ?. Lock

 

# 임계구역(Critical Section) 이란?

공유되는 자원, 즉 동시에 접근하려고 하는 자원에서 문제가 생기지 않게 독점을 보장해야 하는 영역

무슨 말이냐..

 

내가 화잘실에 앉아있다.

배가 아프다.

아윤이가 배가 아프다며 처들어 온다.

모든 경우의 수를 무시하고 처들어온다.

환장한다.

 

여기서 화장실이 나와 아윤이가 공유해야 될 공유자원이고, 내가 잡고 있는 이 문이 임계영역이 된다.

 

동시접근을 해결하기 위해 화장실 문에 잠금장치(Lock)가 있고 조절 가능하다.

 

  • 임계영역이란 프로그램에서 공유 자원의 독점을 보장하는 코드영역, 지정된 시간이 지나면 종료된다.
  • 스레드가 공유자원의 사용을 보장받기 위해서 임계구역에 들어가거나 나올때 동기화 방법이 필요하다.

# Lock

걸어 잠구는 행위

 

간단한 락

class Counter {
    
    private var count:Int = 0
    
    fun inc(): Int {
        synchronized(this) {
            return ++count // 한 시점에 오직 한 쓰레드에 의해서만 수행될 수 있음을 보장한다.
        }
    }
}

 

synchronized 대신 lock을 이용

class Lock {

    private var isLocked = false

    @Synchronized
    @Throws(InterruptedException::class)
    fun lock() {
        while (isLocked) {
            wait()
        }
        isLocked = true
    }

    @Synchronized
    fun unlock() {
        isLocked = false
        notify()
    }
}

class Counter {

    private val lock by lazy { Lock() }
    private var count:Int = 0

    fun inc(): Int {
        lock.lock()
        val newCount = ++count
        lock.unlock()
        return newCount
    }
}

 

  • lock을 걸어 lock()을 호출하는 모든 쓰레드가 unlock()이 호출되기 전까지 대기 시킨다.
  • while 는 스핀 락 이라 불린다.
  • isLocked가 false가 되면 쓰레드는 while루프에서 벗어나 isLocked를 true로 세팅하여 인스턴스가 lock걸렸음을 나타낸다.
  • 임계영역(lock과 unlock사이의 코드)의 코드를 완료한 쓰레드는 unlock()을 호출하여 isLocked를 false로 세팅하고
    lock()에 잠들어있는 쓰레드를 깨운다.

# finally 절에서 unlock() 호출

lock을 이용해서 임계영역을 보호할 때는 임계영역에서 예외가 발생 할 수 있다는 생각을 해야된다. 다른 쓰레드도 lock을 걸 수 있게 반드시 해제 되도록 해야 된다.

 

lock.lock()
try {
    // 임계영역 코드
} finally {
    lock.unlock()
}

예외가 발생한 경우에도 finally에서 lock을 해제한다.

'잡동사니' 카테고리의 다른 글

2020년 회고  (0) 2020.12.29
[study: OS] — ?. Segmentation  (0) 2020.09.14
Clean Code #2 - 의미 있는 이름  (0) 2020.09.13
Clean Code #1 - 깨끗한 코드  (0) 2020.09.08
List Interface  (0) 2020.07.27