OS

[ 동기화 #1 ] 스핀락

qpmi1zm29 2023. 12. 27. 01:04
test_and_set ( &arg ) ?

- 동기화 메커니즘을 코드적으로 표현할 때 사용되는 함수로, 스레드 혹은 프로세스의 원자적 실행을 보장한다.
하드웨어 명령어로 cpu의 도움을 받아 인터럽트가 발생하지 않고, 한 번에 한 스레드 혹은 프로세스만 접근 할 수 있다. 
인자로 받는 값과 응답 값은 0과 1 둘 중 하나이며, 해당 함수의 역할을 인자로 받은 arg의 값을 그대로 return 해줌과 동시에 무조건 1로 set 해준다. 
그래서 while문 안에서 사용될 때 arg의 값이 0이어야지만 while문을 벗어날 수 있다.
소프트웨어 적으로 동기화 기법을 이용한 코드를 작성하여도, 기계어 단계에서 실행될 때 load 및 store 등으로 분할되어 실행되기 때문에 완전한 원자적 실행을 위해서 하드웨어의 도움을 받는다는 개념이다.


 


 

스핀락을 설명하기 전, 관련 용어를 먼저 정리해보자!

race condition : 여러 개의 스레드나 프로세스가 하나의 공유자원에 접근할 때, 덮어쓰기나 실행 순서가 뒤바뀌어 의도하지 않은 결과가 나오는 것을 말한다.

critical section ( 임계영역 ) : 한 번에 하나의 스레드나 프로세스만 처리해야 하는 영역으로, race condition을 발생시키는 코드 영역을 말한다. 

이를 위해서 프로세스 동기화가 필요하게 되었다. 

 

 

스핀락이란 ?

스레드나 프로세스 ( T/P ) 가 임계영역에 접근하기 위해 lock을 취득해야 하는데,

T/P들이 while 루프를 돌면서 lock이 해제되었는지 계속 확인하는 방법을 말한다.

T/P가 다른 일을 하지 않기 때문에 cpu 낭비가 발생하게 된다.

 

public class SpinLock {

    private volatile int lock = 0;

    public void critical() {

        try{
            while ( test_and_set(&lock) ); // 내부적으로 lock = 1 을 해준다.
                                           // acquire lock 부분

            // ~~ 임계영역 ~~

            lock = 0;                      // release lock 부분
    
        }catch( Exception e ){
            lock = 0; // 코드 실행 중 예외 발생 경우를 대비해서 try-catch 문을 통한 
                      // lock 해제 코드가 필수이다. ⭕
        }
        
        
    }
}

 

코드에서 catch 문에 lock 해제를 해주지 않으면 예외 발생 시, lock이 계속 점유상태로 남아 T/P가 무한정 대기 상태로 남게 된다.