1. 락
- 스레드는 공유 자원을 사용하기 때문에 데이터의 정확성을 지키기 위해서는 각각의 스레드를 원자적으로 만들어야 한다.
- 원자적: 더이상 쪼개질 수 없고 한 스레드가 다른 스레드를 방해할 수 없음.
- 각각의 스레드를 원자적으로 만들기 위해서는 상호 배제 메커니즘이 필요하다.
- 이 상호 배제 메커니즘을 달성하게 해주는 것이 어드바이저리 락이다.
- 위쪽 스레드들에서 락을 먼저 하면 아래쪽 스레드들은 락이 해제될 때 까지 기다려야 한다.
- 락이 어드바이저리인 이유는 락을 지킬지 안 지킬지를 사용자가 아닌 프로그램이 결정하기 때문입니다.
- 이럴경우 스레드의 충돌은 해결하지만 한 스레드의 작업이 느리다면 다른 스레드가 오래 기달려야하는 문제가 발생할 수 있어 멀티태스킹의 장점을 잃어버린다.
2. 트랜잭션과 작업 크기
- 성능을 향상할 좋은 방법은 여러 스레드를 한 트랜잭션에 넣는 것이다.
- 트랜잭션에 들어있는 모든 스레드는 모두 다 성공하거나 모두 다 실패해야한다.
- 트랜잭션으로 각 스레드를 독립적으로 수행하는 대신 한꺼번에 묶어서 처리한다.
- 트랜잭션의 작업의 크기(적용범위)를 최소화하고 락 시간을 최소화한다면 락의 성능을 크게 높일 수 있다.
3. 락 대기
- 락을 기다리는 동안 다른 일을 하고 있어야 락의 장점이 커진다.
- 락을 기다리는 동안 스핀 작업을 할 수 있다.
- 스핀작업은 락을 성공적으로 얻을 때까지 락 획득을 반복 시도하는 것이다. 하지만 자원낭비가 심해서 별로 좋은 작업 방식이 아니다.
- 다른 방법으로는 락 요청을 락을 관리하는 쪽에 등록하고 요청이 받아들여진다면 통지를 받는 방법이 있다. 이 방식으로 요청하는 쪽에서는 기다리는 동안 더 유용한 일을 할 수 있다. 다만 락을 사용하는 스레드가 늘어나면 그중 하나에서 문제가 생길 가능성이 커져 규모를 키우는 것은 어렵다.
- 일부 운영체제는 락 기능을 제공하는 데 블로킹이나 비블로킹 모드로 락을 요청할 수 있다.
- 블로킹은 시스템이 락을 할당할 수 있을 때까지 락을 요청한 프로그램을 일시중단 시키는 것이다.
- 논블로킹은 프로그램이 계속 실행되고 나중에 락을 얻었는지 여부를 어떤 방식으로든 통지받게 된다.
4. 교착상태
- 복잡한 시스템에서는 여러 락을 사용하는 경우가 존재한다.
- 예를 들어 락이 2개가 존재한다고 했을 때 만약 프로그램A가 락1을 차지하고 프로그램 B가 락2를 차지하는 상황이라고 해보자. 이 상황에서 프로그램 A는 락 2를 갖고 싶고 프로그램 B는 락1을 차지하고 싶다면 두 프로그램이 모두 자신이 갖고 있는 락을 해제하는 지점으로 진핼할 수 없다.
- 이런 상황을 교착상태라고 한다.
- 교착상태가 발생할 수 있는 경우는 아래 네가지 조건을 만족하는 경우밖에 없다.
- 상호배제: 공유 자원을 함께 쓸 수 없어서 어느 한 프로세스가 독점적으로 사용해야한다.
- 점유대기: 프로세스들은 어느 자원을 점유한 상태에서 다른 자원을 요청한다.
- 비선점: 프로세스가 할당받은 자원을 강제로 빼앗을 수 없다.
- 순환 대기: 각 프로세스가 서로 순환적으로 다른 프로세스가 갖고 있는 자원을 요구한다.
- 이 네가지중 하나라도 없으면 교착상태가 발생하지 않는다. 따라서 아래 네가지 중 한가지 방법만으로 교착상태를 해소할 수 있다.
- 자원을 상호 배제하지 않고 언제든 공유할 수 있는 자원으로 만든다.
- 어느 자원을 점유한 다음 다른 자원을 요구하지 않고 점유하지 않을 때만 그 자원을 요청한다.
- 선점형으로 바꾼다. 즉, 프로세스가 할당받은 자원을 강제로 뺏을 수 있다.
- 자원마다 우선순위를 부여해서 모든 프로세스가 다 서로 정해진 순서대로만 자원을 요구한다.
'CS' 카테고리의 다른 글
동적 메모리 할당, 더 효율적인 메모리 할당, 가비지 컬렉션, 이중 연결 리스트 (0) | 2022.02.16 |
---|---|
파동에 올라타라, 범용직렬버스, 네트워킹 (0) | 2022.02.09 |
메모리상의 데이터 배치, 프로그램 실행 (0) | 2022.02.05 |
시간표현과 상태기억 (0) | 2022.01.29 |
문자를 사용한 수 표현, 색을 표현하는 방법 (0) | 2022.01.21 |